为何subject.onNext(3)会输出?关于sample(500)与setTimeout(200)的RxJS疑问
关于RxJS中sample操作符与subject.onNext(3)输出的疑问解答
嘿,我来帮你搞清楚这个问题~ 其实这两个疑问的核心原因是同一个:RxJS的sample操作符除了按指定时间间隔采样最新值外,当源Observable完成(调用onCompleted())时,会立即发出源Observable的最后一个值,不管设定的采样间隔有没有走完。
我们来一步步拆解你的代码执行流程,就能明白为什么subject.onNext(3)会被输出:
- 初始化
subject和sampleObservable(采样间隔500ms),并订阅后者。 - 调用
subject.onNext(0)和subject.onNext(1):这时候500ms的采样间隔还没到,sample不会触发输出,这两个值会被覆盖,只保留最新的1,但暂时不会发送给订阅者。 - 200ms后进入
setTimeout回调:- 先调用
subject.onNext(2)和subject.onNext(3):此时最新值更新为3,但500ms采样间隔还没到(从程序启动到现在才200ms),所以依然不会立即输出。 - 紧接着调用
subject.onCompleted():这时候源Observable(也就是subject)宣告完成,sample操作符的规则生效——当源完成时,会立即把最后一个缓存的最新值(也就是3)发送给订阅者,所以你就看到了3的输出,随后订阅者的FINISHED也会被打印。
- 先调用
现在对应你的两个疑问:
- 疑问1:为何
subject.onNext(3)会输出?
因为在它之后调用了subject.onCompleted(),触发了sample操作符在源完成时发送最后一个值的逻辑,所以3被输出了。 - 疑问2:已设置
subject.sample(500)但用了setTimeout(200),为何subject.onNext(3)会被输出?
虽然200ms远小于500ms的采样间隔,但subject.onCompleted()的调用触发了sample的完成时特殊逻辑,跳过了等待间隔的步骤,直接发送最后一个值3。
如果把subject.onCompleted()去掉,你会发现3不会被输出——因为500ms采样间隔没到,程序结束前sample没机会触发采样。
内容的提问来源于stack exchange,提问作者Abdul Baten
相关产品推荐
相关产品推荐

