【发布时间】:2017-02-16 07:46:33
【问题描述】:
我正在寻找一个奇怪的边缘情况,其中目录中的文件列表没有显示 0...2 个文件的结果,但对于 3...n 个文件工作正常。
原来可观察到的原始序列运行良好。但是我在一个订阅者中使用了PublishSubject 来传递更改的效果。据报道,所有这些都发生在主队列上,但似乎PublishSubject 在它拥有订阅者之前就获得了馈送值。 (由于没有重播,订阅者不会知道。)
所以所有组件的设置(来源——中继订阅者——消费订阅者)似乎都引入了时间作为一个问题。
奇怪的观察:
- 如果我将原来的
Observable变成Driver,一切正常。 - 如果我在原始链中的某处插入
.observeOn(MainScheduler.instance)(在中继订户之前),一切正常。尽管我可以通过在映射操作中使用断点看到映射已经发生在com.apple.main-queue (serial)上。 - 如果我在来源或订阅者的代码中使用
.subscribeOn(MainScheduler.instance),我仍然会遇到问题。 (可能是因为一开始它只影响中继订阅者,后来为时已晚。)
现在我不明白如何防御性地处理此类问题。
看来PublishSubject 可能不适合这种情况。但是为什么在主队列上观察会改善这种情况呢?
您何时应该(防御性地)指定在主队列上运行的可观察序列在创建/生产时?(同样,这可能是一个实用的修复,但它只是似乎意外地解决了问题。)
或者,换句话说,你应该在什么时候假设消费者的代码没有及时发生,即在订阅设置时?
我无法判断将事件从输入序列中继到PublishSubject 会导致麻烦。这是不可感知的。让我很困惑如何避免这样的错误。
【问题讨论】:
-
你在谈论热与冷的 observables (github.com/Reactive-Extensions/RxJS/blob/master/doc/…)。问题不在于线程或/和时间,而在于您在有人订阅 observable 之前发出项目。想到的两种解决方案:a)仅在订阅后发出信号(冷可观察)或 b)向链添加重播(reactivex.io/documentation/operators/replay.html)
-
是的,归根结底。通过
PublishSubject订阅cold observable 并发出通知事件似乎使我最终消费的东西“热”了。我在自己的代码中没有注意到这一点;我如何让其他人明显区分热/冷?人们是否遵守命名约定,或者您在使用信号时需要先感到惊讶?
标签: swift concurrency rx-swift defensive-programming