RxSwift CombineLatest从上一个Observable发出所有重播的元素

在一组冷的可观察物上使用CombineLatest时,我看到了一些意外的结果。它会发出除最后一个Observable之外的所有消息的最新消息,而是将第一个(n-1)个Observables的最新消息与第n个Observable的每个元素进行合并。

let observable = ReplaySubject<Int>.createUnbounded()
let observable2 = ReplaySubject<String>.createUnbounded()

observable.onNext(1)
observable.onNext(2)
observable.onNext(3)
observable.onNext(4)

observable2.onNext("bed")
observable2.onNext("book")
observable2.onNext("table")

let latestObserver = Observable.combineLatest(observable,observable2)

_ = latestObserver
    .subscribe(onNext: {
    print($0)
})
.disposed(by: disposeBag)

产生输出: (4,“床”) (4,“书”) (4,“表格”)

我原本希望只看到(4,“表”)的输出。

如果我像这样改变可观察对象的顺序:

let latestObserver = Observable.combineLatest(observable2,observable)

我得到的输出: (“表格1) (“表格”,2) (“表3) (“表格”,4)

如果我添加一个最终的任意Observable,那么我只会看到每个前一个的最新的一个:

let observable = ReplaySubject<Int>.createUnbounded()
let observable2 = ReplaySubject<String>.createUnbounded()
let observable3 = Observable<Int>.just(42)

observable.onNext(1)
observable.onNext(2)
observable.onNext(3)
observable.onNext(4)

observable2.onNext("bed")
observable2.onNext("book")
observable2.onNext("table")

let latestObserver = Observable.combineLatest(observable,observable2,observable3)

_ = latestObserver
    .subscribe(onNext: {
    print($0)
})
.disposed(by: disposeBag)

产生输出:(4,“ table”,42)

这真的是预期的行为吗?

hjjhjz 回答:RxSwift CombineLatest从上一个Observable发出所有重播的元素

让我们分解一下您的第一个示例中发生的事情...

您可以使用Observable.from代替主题并获得相同的结果...代码中的步骤如下,

  1. 创建两个ReplaySubject并使用事件加载它们。
  2. combineLatest运算符订阅了第一个主题。
  3. 第一个主题立即重播其所有值。
  4. 由于尚未订阅第二个主题,因此combineLatest运算符不会发出任何内容,而是静默吸收值,同时始终存储“最新”的值。
  5. 然后combineLatest运算符订阅第二个主题。
  6. 该主题重播了所有 值。
  7. 由于combineLatest运算符现在已从其每个来源接收到下一个事件,因此它将发出从第二个来源发出的值以及从第一个来源得到的最新(即最后一个)值。

您的重放主题本质上是同步的。订阅后,它们会立即将所有值发送给订阅者。

在您的最后一个示例代码中,由于三个中的最后一个可观察值仅发出一个值,并且仅在其他两个可观察到的所有值都发出之后,您只能看到一个包含前两个可观察到的最新值的输出。

本文链接:https://www.f2er.com/1294581.html

大家都在问