Angular15中如何让RxJS Interval仅在两个Observable为true时执行?
解决方案
你需要用combineLatest操作符把两个Observable合并,同时获取它们的最新值,再通过filter过滤出两者都为true的情况,之后再用exhaustMap执行播放器状态更新逻辑。具体代码如下:
import { interval, combineLatest, of } from 'rxjs'; import { exhaustMap, filter, mergeMap } from 'rxjs/operators'; // 假设你的两个Observable定义如下: // isYouTubeLoaded: Observable<boolean>; // isPlayerReady: Observable<boolean>; this.YTSubscription = interval(100).pipe( // 每次interval触发时,合并两个Observable的最新状态值 mergeMap(() => combineLatest([this.isYouTubeLoaded, this.isPlayerReady])), // 仅保留两个状态都为true的结果 filter(([isLoaded, isReady]) => isLoaded && isReady), // 执行播放器状态更新,exhaustMap确保前一次逻辑完成后再处理下一次触发 exhaustMap(() => { this.currentTimeSubject.next(this.player.getCurrentTime()); this.isPlayingSubject.next(this.player.getPlayerState() === YT.PlayerState.PLAYING); this.isMutedSubject.next(this.player.isMuted()); this.volumeSubject.next(this.player.getVolume()); return of(true); }) ).subscribe({ error: (err) => { this.YTSubscription?.unsubscribe(); } });
关键操作符说明:
combineLatest([obs1, obs2]):任意一个Observable发出新值时,输出两者最新值组成的数组。配合mergeMap,让每次interval触发都能获取当前两个状态的最新情况。filter:只放行两个状态都为true的结果,确保只有YouTube库加载完成且播放器就绪时,才执行后续状态更新。exhaustMap:和你之前的用法一致,避免前一次状态更新还未完成就触发下一次,防止频繁调用播放器API引发问题。
如果你的isYouTubeLoaded和isPlayerReady变为true后就不再改变(比如加载完成后一直保持true),可以用withLatestFrom替代mergeMap + combineLatest,写法更高效:
import { interval, of } from 'rxjs'; import { exhaustMap, filter, withLatestFrom } from 'rxjs/operators'; this.YTSubscription = interval(100).pipe( withLatestFrom(this.isYouTubeLoaded, this.isPlayerReady), filter(([_, isLoaded, isReady]) => isLoaded && isReady), exhaustMap(() => { // 播放器状态更新逻辑... this.currentTimeSubject.next(this.player.getCurrentTime()); this.isPlayingSubject.next(this.player.getPlayerState() === YT.PlayerState.PLAYING); this.isMutedSubject.next(this.player.isMuted()); this.volumeSubject.next(this.player.getVolume()); return of(true); }) ).subscribe({ error: (err) => { this.YTSubscription?.unsubscribe(); } });
withLatestFrom会在interval触发时直接取两个Observable的当前最新值,无需等待新值发射,适合状态稳定后的场景。
内容的提问来源于stack exchange,提问作者ufk
相关产品推荐
相关产品推荐

