如何将forkJoin与activatedRoute的两个Observable合并?
合并两个Observable并生成指定格式结果
我有如下两个Observable:
第一个Observable
formData$ = forkJoin([ this.httpService.getProgramsLevelsList(), this.httpService.getProgramsTypesList(), this.httpService.getQuestionnaireReasonsList() ]).pipe( tap((res: any) => { console.log(res) }));
该Observable会生成一个包含3个内部数组的结果,示例如下:
[ [arr1], [arr2], [arr3] ]
第二个Observable
existingFormData$: Observable<UniversityApplicationsDetail> = this.activatedRoute.params.pipe( map(params => params['id']), filter(id => !!id), switchMap((id: string) => this.httpService.getUniversityApplicationsDetail(id)) );
该Observable会从URL中获取id(若存在),并从后端返回一个对象;如果URL中没有id,这个Observable不会发出任何值。
需求
能否将这两个Observable合并,得到如下格式的结果?
[ [arr1], [arr2], [arr3], {objApplication} // 该对象可选存在 ]
解决方案
可以通过RxJS的combineLatest结合startWith操作符实现,处理第二个Observable可选的情况:
代码实现
import { combineLatest } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; // 确保第二个Observable始终能发出值(无id时返回null) const existingFormDataWithDefault$ = this.existingFormData$.pipe( startWith(null) ); // 合并两个Observable并构造目标格式 const combinedData$ = combineLatest([this.formData$, existingFormDataWithDefault$]).pipe( map(([formArrays, applicationObj]) => { const result = [...formArrays]; // 仅当存在有效对象时添加到结果中 if (applicationObj) { result.push(applicationObj); } return result; }) );
关键说明
startWith(null):保证existingFormDataWithDefault$总会发出至少一个值,避免因无id导致combineLatest无法触发。combineLatest:当两个Observable都发出值后,将最新值组合传递给下游,适合需要响应路由参数动态变化的场景。- 如果仅需初始化时合并一次(无需响应路由参数变化),可以替换为
forkJoin:
const combinedData$ = forkJoin([ this.formData$, this.existingFormData$.pipe(startWith(null)) ]).pipe( map(([formArrays, applicationObj]) => { const result = [...formArrays]; if (applicationObj) result.push(applicationObj); return result; }) );
内容的提问来源于stack exchange,提问作者Andrew Howard
相关产品推荐
相关产品推荐

