如何按顺序组合两个Observable,为接口返回的数据补充systemName字段
实现方案
使用RxJS的switchMap+forkJoin组合操作符即可实现需求:
import { switchMap, map } from 'rxjs/operators'; import { forkJoin } from 'rxjs'; // 最终输出带systemName字段的Observable this.finalData$ = this.dataService.toGetAllData().pipe( switchMap(dataList => { // 遍历每个数据项,发起对应systemId的查询请求,合并所有请求结果 return forkJoin( dataList.map(item => this.systemService.getSystemById(item.systemId).pipe( map(systemInfo => ({ ...item, // 此处字段根据getSystemById实际返回的系统名称字段调整,示例默认返回name为系统名 systemName: systemInfo.name })) ) ) ) }) ); // 订阅即可拿到目标结果 this.finalData$.subscribe(res => console.log(res));
性能优化版本
如果数据中存在大量重复的systemId,可以增加去重逻辑减少无用请求:
this.finalData$ = this.dataService.toGetAllData().pipe( switchMap(dataList => { // 提取去重后的systemId,避免重复请求 const uniqueIds = [...new Set(dataList.map(i => i.systemId))]; // 批量查询所有唯一id对应的系统信息 return forkJoin(uniqueIds.map(id => this.systemService.getSystemById(id))).pipe( map(systemList => { // 生成systemId到系统名称的映射表 const sysMap = new Map(systemList.map(sys => [sys.id, sys.name])); // 给原数组所有项补全systemName字段 return dataList.map(item => ({ ...item, systemName: sysMap.get(item.systemId) })) }) ) }) );
注意事项
getSystemById返回的系统信息对象中,系统名称的字段名如果不是name,需要自行替换为实际字段forkJoin会等待所有内部请求完成后才统一返回结果,适合并行批量请求场景- 以上写法兼容RxJS 6及以上版本
内容的提问来源于stack exchange,提问作者Desenv Junior
相关产品推荐
相关产品推荐

