RxJS中setTimeout内订阅Subject无输出问题求助
为什么RxJS Subject在setTimeout内的订阅没收到值?
这问题其实是对Subject核心特性的误解,我来给你拆解清楚~
先明确Subject的关键特性
Subject是一种多播Observable,但它有个很重要的特点:只会把订阅之后接收到的next值转发给订阅者,不会回溯发送订阅之前已经发出的值(如果需要能获取最新历史值的特性,应该用BehaviorSubject)。
分析代码片段1的执行流程
我们按代码执行顺序一步步看:
- 创建
subject后,第一个subject.subscribe立即执行,此时Subject有了第一个订阅者。 - 调用
setTimeout,这个回调里的第二个订阅要2秒后才会执行,此时这个订阅动作还没发生。 - 创建自定义Observable,然后执行
observable.subscribe(subject)——这时候Observable的回调函数会立即执行:- 打印
called only once - 调用
observer.next(Math.random()),这个值会被Subject转发给当前已存在的订阅者(也就是第一个subscribe),所以控制台打印出随机数。
- 打印
- 2秒后,第二个订阅才订阅Subject,但这时候Observable早就发送完值了,Subject没有保存之前的发射值,所以这个新订阅者不会收到任何数据,自然没有输出。
分析代码片段2的执行流程
这个就简单了:
- 创建
subject后,连续添加了两个订阅者,这两个订阅都在Observable发送值之前就完成了。 - 当
observable.subscribe(subject)执行时,Observable发送的next值会被Subject转发给这两个已存在的订阅者,所以控制台会打印两次随机数。
总结
如果希望新订阅者能获取到订阅之前的最新值,可以把Subject换成BehaviorSubject,它会保存最近一次发射的值,新订阅者订阅时会立即收到这个值。
内容的提问来源于stack exchange,提问作者21stnomad
相关产品推荐
相关产品推荐

