如何使用switchMap类操作符运行内部Observable且不改变外部值?
解决方案:保留外部Observable原始值的同时运行内部Observable
当然可以实现这个需求——运行switchMap/concatMap里的内部Observable逻辑,但让后续管道接收到外部Observable的原始值。核心思路是:在内部Observable完成后,将其输出转换回原始的外部值,而不是保留内部Observable的结果。
方法1:用mapTo映射回原始值
在内部Observable的管道末尾添加mapTo(i),直接把内部的boolean结果替换为原始的string值:
fsExists = false; projectExists = false; private doChecks = new BehaviorSubject<string>(''); doChecks$ = this.doChecks.pipe( debounceTime(100), tap(i => (this.projectExists = this.projects.exists(i))), switchMap(i => this.fs.exists(path.join(i, environment.manifest)).pipe( tap(exists => (this.fsExists = exists)), // 执行内部逻辑并更新状态 mapTo(i) // 将内部Observable的输出替换为原始的string值 )), tap(i => { /* 这里的i就是原始的string类型了 */ }) );
方法2:用concat拼接内部Observable和原始值Observable
通过concat先执行内部Observable,再发出原始值的Observable,确保后续管道接收到原始值:
import { of, concat } from 'rxjs'; fsExists = false; projectExists = false; private doChecks = new BehaviorSubject<string>(''); doChecks$ = this.doChecks.pipe( debounceTime(100), tap(i => (this.projectExists = this.projects.exists(i))), switchMap(i => concat( this.fs.exists(path.join(i, environment.manifest)).pipe(tap(exists => (this.fsExists = exists))), of(i) // 内部逻辑执行完后,发出原始的string值 )), tap(i => { /* 这里的i是原始的string类型 */ }) );
注意事项
- 如果需要确保内部Observable按顺序执行(不取消之前的请求),只需把
switchMap换成concatMap即可,两种方法的逻辑完全通用。 - 两种方法都会保证内部的文件存在性检查逻辑被执行,同时
fsExists状态会被正确更新,后续管道也能拿到原始的string值。
内容的提问来源于stack exchange,提问作者Get Off My Lawn
相关产品推荐
相关产品推荐

