能否使用takeWhile操作符以另一Observable源作为标识取消订阅?
RxJS 订阅取消需求解答
你目前的写法不能实现预期效果,问题出在两处:
takeWhile操作符要求传入的是谓词函数,你直接传入表达式this.stop$ === false是将stop$Subject 对象本身和布尔值false做全等判断,这个表达式初始化时就永远返回false,会导致你订阅source后立刻就被终止,完全达不到受控取消的效果。takeWhile的判断逻辑只有在源Observable(也就是你的source)每次发射新值的时候才会触发,哪怕你改对了写法,如果你触发取消信号后source一直没有新值发射,订阅也不会被及时取消,完全不符合「收到停止信号立刻终止订阅」的需求。
正确的实现方式
推荐使用RxJS专门为「用另一个Observable触发订阅终止」场景设计的 takeUntil 操作符,代码修改如下:
import { takeUntil } from 'rxjs/operators'; stop$: Subject<boolean> = new Subject<boolean>(); source: Subject<string> = new Subject<string>(); // 直接用takeUntil绑定停止信号 this.source.pipe(takeUntil(this.stop$)).subscribe(() => { // 你的订阅回调逻辑 }); // 需要取消订阅的时候执行以下代码即可 this.stop$.next(true); this.stop$.complete();
非要用takeWhile的兼容写法
如果你确实只能用takeWhile实现,需要额外维护一个状态标记位,写法如下:
stopFlag: boolean = false; stop$: Subject<boolean> = new Subject<boolean>(); source: Subject<string> = new Subject<string>(); // 先订阅停止信号更新标记位 this.stop$.subscribe(val => { this.stopFlag = val; }); // takeWhile传入谓词函数,每次source发射值时判断标记位 this.source.pipe(takeWhile(() => !this.stopFlag)).subscribe(() => { // 你的订阅回调逻辑 });
注意该方案存在前面提到的延迟取消问题,仅做兼容参考,不推荐生产环境使用。
内容的提问来源于stack exchange,提问作者mtnp
相关产品推荐
相关产品推荐

