Angular中concatMap顺序调用链出错后如何中断后续执行
问题场景
我的程序中有一个承载层级结构数据的视图,需要按顺序调用数据库接口填充对应数据结构后再展示视图,若其中某一次调用失败需要立刻中断整个调用流程。
我刚接触Angular,查阅资料得知嵌套subscribe属于不良实践应当避免,因此选用了concatMap来实现顺序调用。但遇到的问题是:若前序调用出错,仍然会跳转到下一个concatMap执行,无可用数据时操作数据结构会抛出非预期的异常,我希望能够中断调用链。
我的实现代码如下:
getData() { this.service.httpCall(null, url + '/test/getallprovinces').pipe( tap( (responsePro) => { if (responsePro.type === 'success') { //fill in data structures } else { //handle error and interrupt throwError("error "); }}), concatMap(() => this.service.httpCall(null, url + '/test/getallcantons')), tap((responseCanton) => { if (responseCanton.type === 'success') { //fill in data structures } else { //handle error and interrupt throwError("error on cantons"); } }), concatMap(() => this.service.httpCall(null, url + '/test/getalldistricts')), tap(responseDis => { if (responseDis.type === 'success') { //fill in data structures } else { //handle error and interrupt throwError("error on districts"); } })) .subscribe( () => {}, error => {console.log("something happened", error)} ); }
原因&解决方案
之前的写法不生效,是因为RxJS的throwError会返回一个Observable对象,仅在被订阅时才会触发错误逻辑。直接在tap回调中调用throwError只是创建了一个未被订阅的Observable,不会被上层流捕获,因此无法中断执行链。
只需要把tap内的throwError调用替换为原生JS异常抛出即可,抛出的异常会被RxJS流自动捕获,直接中断整个执行链,后续的concatMap、tap运算符都不会再执行,最终错误会传递到subscribe的错误回调中统一处理。
修正后的tap逻辑示例:
tap( (responsePro) => { if (responsePro.type === 'success') { // 填充数据结构 } else { // 处理错误并中断 throw new Error("error "); } })
内容的提问来源于stack exchange,提问作者Racertop
相关产品推荐
相关产品推荐

