如何压缩两个发布者但获取最新值而不是 zip 的默认最旧行为?
How to zip two publishers but to get newest values instead of default oldest behavior of zip?
我需要使用 Swift
构建一个 Combine
管道,其中涉及 2 个发布者,pubA(一个 PassThroughSubject)经常生成值,一旦 pubB(另一个 PassThroughSubject)生成一个值,我需要使用来自 pubA 的最新值来触发事件。唯一严格的条件是 - 触发器应该只发生在 pubB(驱动发布者)的新值上,并且管道应该从 pubA 获取最新发布的值(应该跳过旧值)。让我试着用例子来证明:
pubA =>
1
2
3
4
5
pubB => true false true
Expected Output: (true, 3) (false, 5) (true, 5)
最初这似乎对 Zip
有利,但 zip 弹出旧值而不是最新值,即输出变为 (true, 1), (false, 2)。并且只要有来自任何发布者的值,使用 combineLatest
就会触发事件并打破依赖关系,仅在 pubB 的新值上触发,因此输出变为 (true, 3), (true, 4), (true, 5), (假, 5)
感谢任何指点。
编辑笔记:
- 期望得到一对值。
- pubB 正在驱动发布者,对于来自 pubB 的每个值,都会使用来自 pubA 的最新值产生一个事件。
- 如果 pubA 没有产生任何值,它将等到 pubA 产生一个值...因为我们需要一对。
- 如果 pubB 产生的值多于 pubA,则最新的 pubA 值将与最新的 pubB 值配对。
这是我为满足我的确切要求而提出的最终代码。我不愿意从 RxSwift 编写一个自定义的 pub-sub 或端口 combineLatestFrom
到 Combine。
感谢@matt 指导我采用正确的方法,他在这里回答:
import Combine
import Foundation
let pub1 = PassthroughSubject<Int, Never>()
let pub2 = PassthroughSubject<Bool, Never>()
var subscriptions = Set<AnyCancellable>()
pub2.map { value in (unique: UUID(), value: value) }
.combineLatest(pub1)
.removeDuplicates {
return [=10=].0.unique == .0.unique
}
.map { (tuple) in
return (tuple.0.1, tuple.1)
}
.sink { event in
print(event)
}
.store(in: &subscriptions)
pub1.send(1)
pub1.send(2)
pub1.send(2)
pub1.send(3)
pub2.send(true)
pub1.send(4)
pub1.send(5)
pub2.send(false)
pub2.send(true)
输出是:
(正确,3)
(错误,5)
(正确,5)
我需要使用 Swift
构建一个 Combine
管道,其中涉及 2 个发布者,pubA(一个 PassThroughSubject)经常生成值,一旦 pubB(另一个 PassThroughSubject)生成一个值,我需要使用来自 pubA 的最新值来触发事件。唯一严格的条件是 - 触发器应该只发生在 pubB(驱动发布者)的新值上,并且管道应该从 pubA 获取最新发布的值(应该跳过旧值)。让我试着用例子来证明:
pubA =>
1
2
3
4
5
pubB => true false true
Expected Output: (true, 3) (false, 5) (true, 5)
最初这似乎对 Zip
有利,但 zip 弹出旧值而不是最新值,即输出变为 (true, 1), (false, 2)。并且只要有来自任何发布者的值,使用 combineLatest
就会触发事件并打破依赖关系,仅在 pubB 的新值上触发,因此输出变为 (true, 3), (true, 4), (true, 5), (假, 5)
感谢任何指点。
编辑笔记:
- 期望得到一对值。
- pubB 正在驱动发布者,对于来自 pubB 的每个值,都会使用来自 pubA 的最新值产生一个事件。
- 如果 pubA 没有产生任何值,它将等到 pubA 产生一个值...因为我们需要一对。
- 如果 pubB 产生的值多于 pubA,则最新的 pubA 值将与最新的 pubB 值配对。
这是我为满足我的确切要求而提出的最终代码。我不愿意从 RxSwift 编写一个自定义的 pub-sub 或端口 combineLatestFrom
到 Combine。
感谢@matt 指导我采用正确的方法,他在这里回答:
import Combine
import Foundation
let pub1 = PassthroughSubject<Int, Never>()
let pub2 = PassthroughSubject<Bool, Never>()
var subscriptions = Set<AnyCancellable>()
pub2.map { value in (unique: UUID(), value: value) }
.combineLatest(pub1)
.removeDuplicates {
return [=10=].0.unique == .0.unique
}
.map { (tuple) in
return (tuple.0.1, tuple.1)
}
.sink { event in
print(event)
}
.store(in: &subscriptions)
pub1.send(1)
pub1.send(2)
pub1.send(2)
pub1.send(3)
pub2.send(true)
pub1.send(4)
pub1.send(5)
pub2.send(false)
pub2.send(true)
输出是:
(正确,3)
(错误,5)
(正确,5)