如何压缩两个发布者但获取最新值而不是 zip 的默认最旧行为?

问题描述

我需要使用 Combine 构建一个 Swift 管道,其中涉及 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),5),(假,5)

感谢任何指点。

编辑备注:

  1. 期望得到一对值。
  2. pubB 正在推动发布者,对于来自 pubB 的每个值,都会有一个使用来自 pubA 的最新值的事件。
  3. 如果 pubA 没有产生任何值,它将一直等到 pubA 产生一个值......因为我们需要一对。
  4. 如果 pubB 产生的值多于 pubA,则最新的 pubA 值将与最新的 pubB 值配对。

解决方法

这是我想出的符合我的确切要求的最终代码。我不愿意从 RxSwift 编写自定义发布订阅或端口 combineLatestFrom 到 Combine。 感谢@matt 指导我采用正确的方法,他在这里回答:Swift Combine operator with same functionality like `withLatestFrom` in the RxSwift Framework

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 $0.0.unique == $1.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)