ios - 如何从发布者数组中创建发布者?
问题描述
我正在使用 Swift Combine 并希望Publisher
创建一个从Publisher
. 每当数组中的一个发布者发出一个新元素时,它应该发出一个元素数组。
在RxSwift
将如下所示:
let obs1 = PublishSubject<Int>()
let obs2 = PublishSubject<Int>()
let arrayObs = [obs1, obs2)]
Observable.combineLatest(arrayObs)
.subscribe(onNext: { arrayOfLatest in
print(arrayOfLatest) //prints an array of integers
}).disposed(by: disposeBag)
obs1.onNext(5)
obs2.onNext(10) // prints [5,10]
obs1.onNext(12) // prints [12,10]
解决方案
只要您对“数组”部分没有太强烈的坚持,combineLatest
或者zip
对组合框架也是正确的。它们之间的区别在于您是否希望每次发出的总价值包含来自每个发布者的最旧( zip
) 或最新( combineLatest
) 贡献。
您的示例实际上并没有提供足够的信息来说明您想要哪些。要知道你想要哪个,你需要说出当你说例如应该发生什么:
obs1.onNext(5)
obs1.onNext(6)
obs2.onNext(10)
尽管如此,Combine 是 Swift,所以它使用元组而不是数组来表达值的整体。但是,如果像您的示例一样,所有发布者都具有相同的输出和失败类型,则可以轻松地通过映射替换数组。请参阅如何压缩 4 个以上的发布zip
者,了解如何转换为阵列处理器的示例。完全相同的技术适用于combineLatest
.
所以,这是一个实际的工作示例;为了使示例比您的示例更通用,我使用了三个发布者而不是两个:
class ViewController: UIViewController {
let obs1 = PassthroughSubject<Int,Never>()
let obs2 = PassthroughSubject<Int,Never>()
let obs3 = PassthroughSubject<Int,Never>()
var storage = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
let arr = [obs1, obs2, obs3]
let pub = arr.dropFirst().reduce(into: AnyPublisher(arr[0].map{[$0]})) {
res, ob in
res = res.combineLatest(ob) {
i1, i2 -> [Int] in
return i1 + [i2]
}.eraseToAnyPublisher()
}
pub.sink { print($0) }.store(in: &storage)
obs1.send(5)
obs2.send(10)
obs3.send(1) // [5, 10, 1]
obs1.send(12) // [12, 10, 1]
obs3.send(20) // [12, 10, 20]
}
}
推荐阅读
- python - 将特定时间字符串转换为数据时间 pandas
- email - 如何在没有现有用户帐户的情况下创建接收邮件的电子邮件服务器?
- javascript - 跨域请求即使带有标头也被阻止
- mysql - 获取按交替列值分组的行
- r - 通过匹配 ID 号创建 iGraph 对象
- reactjs - Django Rest Framework 身份验证和用户会话
- android - Android Compose 以像素为单位设置视图高度,不在 dp 中
- mongodb - VS Code MongoDB Playground 无法识别基本语法
- mariadb - 即使端口已更改,MariaDB 也未启动
- swift - SwiftUI / Firestore“无法将'String'类型的值转换为预期的参数类型''