我是组合框架的新手,所以我的问题可能很简单。 我正在尝试合并来自多个发布商的值并发送值,即使收到的值是某些发布商尚未发布的值。
这是我现在所拥有的:
return Publishers
.CombineLatest(somePublisher, otherPublisher)
.map { (somePublisherValues, otherPublisherValue) in
return [
somePublisher,
otherPublisherValue
]
}
.removeDuplicates()
.eraseToAnyPublisher()
两家出版商在所有情况下都会发布,因此工作正常。 现在我需要添加第三个:thirdPublisher。
- somePublisher 和thirdPublisher 都可以发布
- 某些发布者可能不会发布
- 第三发布者不得发布
如何在以前的情况下的所有情况下发送响应,例如:
- 返回 [somePublisher、otherPublisherValue、thirdPublisherValue]
- 返回 [nil、otherPublisherValue、thirdPublisherValue]
- 返回 [somePublisher, otherPublisherValue, nil]
我尝试过:
return Publishers
.CombineLatest3(somePublisher, otherPublisher, thirdPublisher)
.map { (somePublisherValues, otherPublisherValue, thirdPublisherValue) in
return [
somePublisher,
otherPublisherValue,
thirdPublisher
]
}
.removeDuplicates()
.eraseToAnyPublisher()
但它不会发布,因为一些发布者不在场。
最佳答案
CombineLatest
被设计为仅在其所有上游发布者发出第一个值后才发出。如果您希望在任何上游发出后立即发出并为所有缺失值发送 nil
,您可以映射所有上游以发出 Optional
值并强制它们使用 prepend(nil)
在任何实际值之前发送 nil
。
这样,您将在实际输出之前收到一个 [nil, nil, ...]
值(您可以使用 dropFirst
忽略该值),然后您将开始收到所需的输出。
let publisher: PassthroughSubject<Int, Never> = .init()
let publisher2: PassthroughSubject<Int, Never> = .init()
let optionalPublisher = publisher.map(Optional.init).prepend(nil)
let optionalPublisher2 = publisher2.map(Optional.init).prepend(nil)
let combined = Publishers.CombineLatest(optionalPublisher, optionalPublisher2)
combined.sink {
print("CombineLatest emitted \($0)")
}.store(in: &subscriptions)
publisher.send(1)
publisher2.send(1)
publisher.send(2)
输出:
CombineLatest emitted (nil, nil)
CombineLatest emitted (Optional(1), nil)
CombineLatest emitted (Optional(1), Optional(1))
CombineLatest emitted (Optional(2), Optional(1))
关于使用CombineLatest 与可选发布者进行 Swift 组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73950560/