RxSwift中第二个订阅者为何能接收全部元素?
问题解答:RxSwift中延迟订阅仍收到全部元素的原因
你遇到的核心问题是冷Observable的特性导致的:
- 你用
Observable.create创建的mainObservable是一个冷Observable,它的本质是每次有订阅者订阅时,都会重新执行一次创建闭包里的逻辑。 - 第一个订阅者订阅时,闭包立刻执行,发送全部5个元素;2秒后第二个订阅者订阅时,闭包会再次执行一遍,重新发送所有5个元素,所以第二个订阅者能收到完整序列。
如果想要实现“第二个订阅者错过前面元素”的效果,需要把冷Observable转换成热Observable,让所有订阅者共享同一序列的发射。常用的操作符有:
share():自动连接,当第一个订阅者订阅时开始发射,后续订阅者接收当前及之后的元素publish()+connect():手动控制序列的发射时机
举个修改后的例子,用share()实现:
import RxSwift import Foundation let disposeBag = DisposeBag() // 转换成热Observable,共享序列 let mainObservable = Observable<String>.create { observer in observer.onNext("Element 1") observer.onNext("Element 2") observer.onNext("Element 3") observer.onNext("Element 4") observer.onNext("Element 5") observer.onCompleted() return Disposables.create() }.share() // 添加share操作符 mainObservable.subscribe(onNext: { element in print("listener1 received: \(element)") }, onCompleted: { print("listener1 completed") }).disposed(by: disposeBag) DispatchQueue.main.asyncAfter(deadline: .now() + 2) { mainObservable.subscribe(onNext: { element in print("listener2 received: \(element)") }, onCompleted: { print("listener2 completed") }).disposed(by: disposeBag) }
这个修改后的代码中,第二个订阅者在2秒后订阅时,原序列已经完成,所以不会收到任何元素。如果序列是持续发射的(比如定时器),第二个订阅者会收到订阅之后的元素。
内容的提问来源于stack exchange,提问作者AlanSTACK
相关产品推荐
相关产品推荐

