BehaviorSubject用repeat失效原因及定时重发+重置方案问询
问题分析:
repeat 对 BehaviorSubject 无效的原因 of('Observable')是冷Observable,每次订阅都会从头发射值并自动完成,repeat会在上游完成后触发重订阅,所以能每秒重复输出。- BehaviorSubject属于热Observable/Subject,它不会自动完成(除非主动调用
complete()),而repeat的触发条件是上游Observable完成,因此repeat根本没有执行重订阅的机会,自然不会重复发射值。
基础需求:每隔固定时间重发最后一个值
如果不需要新值重置定时器,只想持续重复BehaviorSubject的最新值,可以用interval结合withLatestFrom实现:
import { BehaviorSubject, interval, withLatestFrom, map } from 'rxjs'; const bs = new BehaviorSubject('BehaviorSubject'); interval(1000) .pipe(withLatestFrom(bs)) .pipe(map(([_, value]) => value)) .subscribe(x => console.log(x));
思路很简单:用interval每秒触发一次,每次触发时取BehaviorSubject的当前值输出。
进阶需求:新值触发时重置定时器
针对你提到的“新值到来时重置定时器”的需求,你的switchMap思路是正确的,这里优化写法让它更简洁优雅:
import { BehaviorSubject, timer } from 'rxjs'; import { switchMap, map } from 'rxjs/operators'; const bs = new BehaviorSubject('BehaviorSubject'); bs.pipe( // 每次新值进来就切换到新的定时序列,旧定时器直接取消 switchMap(value => timer(0, 1000).pipe(map(() => value))) ).subscribe(x => console.log(x));
timer(0, 1000)会先立即输出一次,之后每秒输出一次;map把定时器的输出转换成当前的BehaviorSubject值;switchMap会在BehaviorSubject发射新值时,自动取消之前的定时器订阅,重新启动新的定时序列,完美实现“新值重置定时器”的效果。
内容的提问来源于stack exchange,提问作者moi_meme
相关产品推荐
相关产品推荐

