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

RxJS中setTimeout内订阅Subject无输出问题求助

为什么RxJS Subject在setTimeout内的订阅没收到值?

这问题其实是对Subject核心特性的误解,我来给你拆解清楚~

先明确Subject的关键特性

Subject是一种多播Observable,但它有个很重要的特点:只会把订阅之后接收到的next值转发给订阅者,不会回溯发送订阅之前已经发出的值(如果需要能获取最新历史值的特性,应该用BehaviorSubject)。

分析代码片段1的执行流程

我们按代码执行顺序一步步看:

  1. 创建subject后,第一个subject.subscribe立即执行,此时Subject有了第一个订阅者。
  2. 调用setTimeout,这个回调里的第二个订阅要2秒后才会执行,此时这个订阅动作还没发生。
  3. 创建自定义Observable,然后执行observable.subscribe(subject)——这时候Observable的回调函数会立即执行:
    • 打印called only once
    • 调用observer.next(Math.random()),这个值会被Subject转发给当前已存在的订阅者(也就是第一个subscribe),所以控制台打印出随机数。
  4. 2秒后,第二个订阅才订阅Subject,但这时候Observable早就发送完值了,Subject没有保存之前的发射值,所以这个新订阅者不会收到任何数据,自然没有输出。

分析代码片段2的执行流程

这个就简单了:

  1. 创建subject后,连续添加了两个订阅者,这两个订阅都在Observable发送值之前就完成了。
  2. 当observable.subscribe(subject)执行时,Observable发送的next值会被Subject转发给这两个已存在的订阅者,所以控制台会打印两次随机数。

总结

如果希望新订阅者能获取到订阅之前的最新值,可以把Subject换成BehaviorSubject,它会保存最近一次发射的值,新订阅者订阅时会立即收到这个值。


内容的提问来源于stack exchange,提问作者21stnomad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:19:53