Angular 11:forkJoin/zip中第二个Observable失败时不取消第一个的方法
并行请求部分失败仍保留成功结果的解决办法
你现在用的forkJoin有个特点:只要其中任何一个Observable抛出错误,整个组合流就会直接触发错误回调,而且不会返回任何已经完成的请求结果。要实现第二个请求失败时不影响第一个结果的获取,核心办法是给可能失败的Observable单独加错误捕获,让它在失败时返回一个能识别的“失败标记”,而不是直接中断整个流。
具体代码实现
针对单个易失败请求处理
如果只有第二个请求b可能失败,给它加catchError操作符,捕获错误后返回包含错误信息的对象:
import { forkJoin, of, catchError } from 'rxjs'; // 给b做错误防护,失败时返回带错误标记的对象 const safeB = b.pipe( catchError(err => of({ isError: true, msg: err.message })) ); forkJoin([a, safeB]) .subscribe({ next: ([firstRes, secondRes]) => { // 第一个请求的结果肯定能拿到(除非a自己出错) console.log('第一个请求返回:', firstRes); // 判断第二个请求的状态 if (secondRes.isError) { console.log('第二个请求失败:', secondRes.msg); } else { console.log('第二个请求返回:', secondRes); } }, error: (err) => { // 只有a本身出错时才会走到这里 console.log('第一个请求失败:', err); } });
针对所有请求做容错处理
如果两个请求都可能失败,且希望互不影响,给两个都加上错误捕获:
const safeA = a.pipe( catchError(err => of({ isError: true, msg: err.message })) ); const safeB = b.pipe( catchError(err => of({ isError: true, msg: err.message })) ); forkJoin([safeA, safeB]) .subscribe({ next: ([firstRes, secondRes]) => { // 分别处理每个请求的成功/失败 if (firstRes.isError) { console.log('第一个请求挂了:', firstRes.msg); } else { console.log('第一个请求结果:', firstRes); } if (secondRes.isError) { console.log('第二个请求挂了:', secondRes.msg); } else { console.log('第二个请求结果:', secondRes); } } // 这里的error回调不会触发,因为所有错误都被提前捕获了 });
原理说明
catchError的作用就是捕获Observable抛出的错误,然后返回一个新的Observable让流继续执行,这样forkJoin就不会因为某个子请求失败而直接终止。通过返回带标记的对象,我们就能在回调里清楚区分每个请求的状态,既拿到成功的数据,也能处理失败的情况。
内容的提问来源于stack exchange,提问作者Boris Adamyan
相关产品推荐
相关产品推荐

