为何RxJS的switchMap仅输出of()源Observable的最后一个值?
为什么RxJS中switchMap只输出最后一个值?
先看两段对比代码:
使用map的情况
of('foo', 'bar') .pipe(map((val) => sanitizer(val))) .subscribe((val) => console.log('value:', val)); function sanitizer(val: string) { return val; }
输出:
value: foo value: bar
使用switchMap的情况
of('foo', 'bar') .pipe(switchMap((val) => sanitizer(val))) .subscribe((val) => console.log('value:', val)); async function sanitizer(val: string) { return val; }
输出:
value: bar
原因解析
switchMap的核心特性是当源Observable发射新值时,会立即取消之前内部Observable的订阅,只保留最新的内部Observable的订阅。
在这个例子里:
of('foo', 'bar')是同步发射值的,会几乎同时把两个值都推送出去。- 标记了
async的sanitizer函数返回的是Promise,RxJS会自动将其转换为Observable。 - 当源发射'foo'时,switchMap订阅了对应'foo'的Observable;但紧接着源就发射了'bar',switchMap立刻取消了前一个Observable的订阅,转而订阅对应'bar'的Observable。
- 虽然对应'foo'的Promise已经执行,但因为订阅被取消,它的结果不会被推送给订阅者,最终只有最后一个'bar'的结果被输出。
解决办法
如果希望每个值都被处理并输出,可以根据需求选择:
- mergeMap:同时处理所有内部Observable,不取消之前的订阅,结果顺序可能和发射顺序不一致(如果内部操作是异步的)。
- concatMap:按顺序处理,前一个内部Observable完成后再处理下一个,结果顺序和源发射顺序一致。
内容的提问来源于stack exchange,提问作者Wajahath
相关产品推荐
相关产品推荐

