如何实现先请求成功再发起二次请求并合并响应为单个Observable?
解决方案:顺序执行接口请求并获取合并响应
问题分析
你需要实现顺序请求逻辑:先调用第一个接口,仅当它返回有效数据时再发起第二个请求,最终在subscribe中一次性获取两个接口的响应。现有方案存在以下问题:
concat会分两次触发next,分别返回单个请求的响应,无法一次性拿到合并结果mergeMap仅传递第二个请求的响应,丢失第一个请求的数据forkJoin会因任一请求失败而终止整个流,无法保留已成功请求的结果
实现代码
使用concatMap(保证顺序执行)结合map合并两个请求的响应,同时通过catchError处理第二个请求的错误,确保第一个请求的结果不会丢失:
getInfo(fileNumber: number) { this.proceedingsService.getActByFileNumber(fileNumber).pipe( // 过滤第一个接口的无效响应,仅当有数据时继续执行第二个请求 filter(firstRes => !!firstRes), // 顺序发起第二个请求,并合并两个响应 concatMap(firstRes => this.detailProceedingsDevolutionService.getDetailProceedingsDevolutionByExpedient(fileNumber).pipe( map(secondRes => ({ act: firstRes, devolution: secondRes })) ) ), // 处理第二个请求的错误,保留第一个请求的结果 catchError((err, caught) => { console.error('第二个请求失败:', err); // 从流中获取第一个请求的结果,可根据实际场景调整存储方式 return caught.pipe(take(1), map(firstRes => ({ act: firstRes, devolution: null, error: err }))); }) ).subscribe({ next: combinedData => { console.log('合并响应:', combinedData); this.prepareData(combinedData); }, error: err => { console.error('第一个请求失败:', err); } }); }
代码说明
- 过滤无效响应:
filter操作符确保仅当第一个接口返回有效数据时,才继续执行后续逻辑 - 顺序请求与合并结果:
concatMap保证第二个请求在第一个请求完成后发起,内部通过map将两个响应合并为一个对象,让subscribe的next仅触发一次 - 错误处理:
catchError捕获第二个请求的错误,同时保留第一个请求的结果,避免整个流终止;第一个请求的错误会直接进入subscribe的error回调
自定义调整点
- 根据第一个接口的返回结构修改
filter的判断逻辑:比如返回数组时用firstRes.length > 0,返回对象时用Object.keys(firstRes).length > 0 - 合并结果的格式可以改为数组
[firstRes, secondRes],适配prepareData方法的参数要求 - 若不需要保留第二个请求的错误信息,可简化
catchError为return of({ act: firstRes, devolution: null })
内容的提问来源于stack exchange,提问作者JulianProg
相关产品推荐
相关产品推荐

