You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何subject.onNext(3)会输出?关于sample(500)与setTimeout(200)的RxJS疑问

关于RxJS中sample操作符与subject.onNext(3)输出的疑问解答

嘿,我来帮你搞清楚这个问题~ 其实这两个疑问的核心原因是同一个:RxJS的sample操作符除了按指定时间间隔采样最新值外,当源Observable完成(调用onCompleted())时,会立即发出源Observable的最后一个值,不管设定的采样间隔有没有走完。

我们来一步步拆解你的代码执行流程,就能明白为什么subject.onNext(3)会被输出:

  1. 初始化subject和sampleObservable(采样间隔500ms),并订阅后者。
  2. 调用subject.onNext(0)和subject.onNext(1):这时候500ms的采样间隔还没到,sample不会触发输出,这两个值会被覆盖,只保留最新的1,但暂时不会发送给订阅者。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:25:36