Observable.of(x)与repeatWhen组合出现异常行为的疑问
为什么Observable.of()和repeatWhen一起用会重复发射同一个值?
嘿,这个问题其实是RxJS里Observable.of()的核心特性导致的,完全属于预期行为,咱们一步步理清楚:
核心原因:Observable.of()是创建时求值,而非订阅时
当你调用Observable.of(count)的时候,RxJS会立即捕获当前count的数值(也就是你初始的5),并把这个固定值封装到Observable中。这个Observable的行为是固定的:每次被订阅时,都会同步发射这个预先捕获的5,然后立即完成。
而repeatWhen的作用是,在源Observable完成后,根据你传入的通知流(比如一个定时器)来触发重新订阅源Observable。但问题在于,你重新订阅的还是那个已经把值固定为5的Observable,所以每次都会得到同样的5,而不是你期望的递增数值。
举个你的代码场景例子
假设你的代码大概是这样的:
let count = 5; const source = Observable.of(count); source.pipe( repeatWhen(() => interval(1000)) ).subscribe(val => console.log(val));
这里source在创建时就已经把count=5锁死了,后续每次repeatWhen触发订阅,都是发射这个固定的5,自然就得到5 5 5...的输出。
如何实现你预期的递增输出?
要让每次订阅时都重新计算数值,你需要用defer()操作符来包装你的Observable创建逻辑。defer()会延迟Observable的创建,直到每次订阅发生时才执行内部的函数,这样就能每次都获取最新的count值:
import { defer, of, interval } from 'rxjs'; import { repeatWhen } from 'rxjs/operators'; let count = 5; const source = defer(() => of(count += 5)); source.pipe( repeatWhen(() => interval(1000)) ).subscribe(val => console.log(val));
现在每次repeatWhen触发订阅,defer()都会执行of(count +=5),count会每次递增5,最终输出就是你想要的5 10 15 20...。
总结一下
Observable.of()是创建时求值,参数值在Observable创建时就被固定,后续订阅不会重新计算。repeatWhen会重复订阅源Observable,但如果源Observable的值是固定的,自然每次输出都一样。- 这完全是RxJS的预期行为,符合Observable的设计原则:冷Observable的每次订阅都会重放序列,但如果序列本身是固定值,那结果就是重复相同的值。
内容的提问来源于stack exchange,提问作者Elias
相关产品推荐
相关产品推荐

