RxJS嵌套订阅时如何直接获取内层订阅实际数据而非Observable对象
RxJS嵌套订阅获取内层实际数据解决方案
问题根源
当前代码返回[Observable, Observable, Observable, Observable]的核心原因:
- 外层
map操作符仅做值转换,不会自动订阅、展开内层的Observable对象,遍历生成的subscription2 Observable数组会被直接传递到下游 - 内层
map返回of(data3)属于冗余操作,of会把普通值再次包装成Observable,额外增加了嵌套层级
修正方案
需要使用RxJS高阶映射操作符+多Observable组合操作符处理内层嵌套流,这里推荐用concatMap(按顺序处理不取消前序请求,可根据业务替换为switchMap/mergeMap) + forkJoin(并行执行所有内层Observable,统一返回结果数组):
import { forkJoin } from 'rxjs'; import { concatMap, takeUntil } from 'rxjs/operators'; this.subscription1$ .pipe( takeUntil(this.ngUnsubscribe), // 替换外层map为高阶映射操作符,切换到内层组合流 concatMap((data1) => { // 遍历生成所有subscription2的Observable数组 const innerObservables = data1.map((data2, index) => { return this.subscription2(index + 1).pipe( takeUntil(this.ngUnsubscribe) // 不需要套of包一层,直接返回原始data3即可 ); }); // forkJoin组合所有内层Observable,全部完成后发射结果数组 return forkJoin(innerObservables); }) ) .subscribe((data) => { console.log('FINAL: ', data); // 此处拿到的就是内层返回的实际值数组 });
注意事项
- 如果
subscription2是不会自动完成的长流,需要在它的pipe中添加take(1),保证forkJoin能正常触发返回 - 如果不需要等所有内层请求完成再返回,而是要逐个获取内层返回值,可以把
forkJoin替换为merge,下游subscribe会逐个接收每个subscription2的返回值 - 可根据业务场景选择高阶映射操作符:
concatMap:按顺序执行内层Observable,前一个完成才会执行下一个mergeMap:并发执行所有内层Observable,结果顺序和发射顺序一致switchMap:如果外层subscription1$发射新值,会取消还在执行的内层Observable,仅保留最新请求
内容的提问来源于stack exchange,提问作者Dani
相关产品推荐
相关产品推荐

