RxJS如何在操作符中同时使用源Observable与内部输入值?
解决方案
你的核心问题在于当前的multiply是先接收固定factor,再接收源Observable的高阶操作符,当factor需要从源值内部获取时,就不得不通过switchMap手动包装源值成新Observable,导致冗余。
重构方案1:让自定义操作符支持从源值中提取factor
修改multiply,让它接收一个选择器函数,这个函数负责从源值中取出需要的factor。这样操作符内部就能直接访问源值的val和提取到的factor,无需手动传递源Observable:
import { Observable, map } from 'rxjs'; source$ = of({ val: 5, factor: 6, factorTwo: 3 }); // 重构后的multiply操作符:接收选择器函数获取factor multiply(getFactor: (value: typeof this.source$['value']) => number) { return (source: Observable<typeof this.source$['value']>) => source.pipe(map(value => value.val * getFactor(value))); } // 直接使用,无需switchMap simpleUsage$ = this.source$.pipe(this.multiply(() => 1)); // 固定factor=1 WithFactorOne$ = this.source$.pipe(this.multiply(x => x.factor)); // 取x.factor WithFactorTwo$ = this.source$.pipe(this.multiply(x => x.factorTwo)); // 取x.factorTwo
重构方案2:放弃高阶操作符,直接用普通函数配合map
如果不需要复用操作符的形式,直接写一个计算函数,配合原生map更简单:
// 普通计算函数 calcMultiply(value: { val: number; factor: number }) { return value.val * value.factor; } calcMultiplyTwo(value: { val: number; factorTwo: number }) { return value.val * value.factorTwo; } // 使用 simpleUsage$ = this.source$.pipe(map(x => x.val * 1)); WithFactorOne$ = this.source$.pipe(map(this.calcMultiply)); WithFactorTwo$ = this.source$.pipe(map(this.calcMultiplyTwo));
为什么之前的desieredFactor$写法不生效?
你写的map(x => this.multiply(x.factor)),本质是把每个源值转换成了一个高阶操作符函数(类型是(source: Observable<...>) => Observable<number>),而不是最终的数值Observable。这也是为什么必须用switchMap去执行这个函数,但我们通过重构操作符的设计,从根源上避免了这种冗余。
内容的提问来源于stack exchange,提问作者PEPEGA
相关产品推荐
相关产品推荐

