RxJS多Observable订阅冲突处理:同时触发仅执行指定订阅
解决方案
要实现「当resizeEnd和stateChange同时触发时,只执行resizeEnd的逻辑、忽略stateChange」的需求,可以通过标记resize状态并过滤stateChange事件的方式实现,具体步骤如下:
- 先创建一个用于跟踪resize触发状态的Observable,当
resizeEnd触发时标记为「正在处理resize」,并在短时间后重置状态(避免长期阻塞stateChange):
import { concat, of, timer, switchMap, startWith } from 'rxjs'; // resizeEnd触发后100ms内保持活跃标记,可根据实际场景调整延迟时长 const resizeActive$ = this.windowRef.window.instance.resizeEnd.pipe( takeUntilDestroyed(this.destroyRef), switchMap(() => concat(of(true), timer(100).pipe(mapTo(false)))), startWith(false) );
- 保留
resizeEnd的原有订阅逻辑:
this.windowRef.window.instance.resizeEnd .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { // ... some code });
- 修改
stateChange的订阅,结合resizeActive$过滤掉resize活跃期间的事件:
import { withLatestFrom, filter, map } from 'rxjs'; this.windowRef.window.instance.stateChange .pipe( takeUntilDestroyed(this.destroyRef), // 获取当前resize的活跃状态 withLatestFrom(resizeActive$), // 仅当resize不活跃时,才处理stateChange事件 filter(([_, isResizing]) => !isResizing), // 提取原始的state数据 map(([state]) => state) ) .subscribe((state) => { // ... some code });
原理说明
resizeActive$会在resizeEnd触发时立即发出true,100ms后自动切换为false,确保与resizeEnd同时触发的stateChange事件会被过滤掉。- 延迟时长可根据实际事件触发的时间差调整,既保证
resizeEnd逻辑优先执行,也不会长期阻塞stateChange的正常触发。
内容的提问来源于stack exchange,提问作者andy
相关产品推荐
相关产品推荐

