【发布时间】:2020-11-02 02:42:21
【问题描述】:
在对一组冷的 observable 使用 combineLatest 时,我看到了一些意想不到的结果。它从除最后一个 Observable 之外的所有 Observable 中发出最新的,而是将第一个 (n-1) 个 Observable 中的最新与来自第 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, "table") 的输出。
如果我像这样更改可观察对象的顺序:
let latestObserver = Observable.combineLatest(observable2, observable)
我得到输出: (“表格1) (“表”,2) (“表3) (“表”,4)
如果我添加一个最终的任意 Observable,那么我只会看到第一个 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)
这真的是预期的行为吗?
【问题讨论】:
-
基于这个问题,以及您的最后一个问题,我的印象是您无法跟踪哪些可观察对象是同步的,哪些是异步的......
-
@DanielT。确实。无需过多介绍,它源于模型的协议规范作为视图控制器的输入。该协议指定了我以前习惯于查看 BehaviorRelay 或 BehaviourSubject 的 Observables。视图控制器应该只根据最新值更新其显示和控件,并忽略任何中间重放值。只是试图了解协议的各种可能的未来具体实现的后果 - 这可能超出我的控制范围。我以为我理解了一些事情,但发现了一些惊喜。谢谢
-
啊,我明白了...无论如何,您都应该避免使用主题(包括 ReplaySubject。)也许这将帮助您避免首先发出所有这些“中间重播值”。 Subjects 只能用于将非 Rx 代码转换为 Rx 并处理依赖循环(其中 Observable 的输出会影响其自身的输入。)