RxJs使用concatMap执行多请求后发起单个请求失效问题求解
问题核心原因
你当前的写法有两个核心问题:
- 你将收尾请求的
concatMap直接挂载在from(response.barcodes)的管道中,from会把数组拆分为逐个发射的元素流,每个barcode请求完成后都会触发后续的concatMap,因此会导致收尾请求执行多次。 - 首项请求完成后流程停止的问题,大概率是你的收尾请求执行过程中抛出了未捕获的错误,直接中断了整个响应流,导致后续的barcode请求没有继续执行。
修复方案
你可以使用toArray操作符等待所有barcode请求全部执行完成后,再触发唯一一次收尾请求,参考代码如下:
return this.expeditionService.getTranssmartBookingXml(request).pipe( concatMap((response) => { // 构造所有barcode保存的请求流 const saveAllBarcodes$ = from(response.barcodes).pipe( concatMap((barcode) => this.expeditionService.saveTranssmartBarcode({ ...saveBarcodeRequest, barcode })), // 等待所有barcode请求完成,将所有返回结果汇总为数组后再向下发射 toArray() ); // 所有barcode处理完成后执行唯一一次收尾请求 return saveAllBarcodes$.pipe( concatMap(() => { const transsmartSaveShipmentRequest: TranssmartSaveShipmentRequest = { reference: this.shipmentReferenceResult!.reference, price: this.transsmartDoBookingResponse!.price, trackingUrl: this.transsmartDoBookingResponse!.trackingUrl }; return this.expeditionService.saveTranssmartShipment(transsmartSaveShipmentRequest); }) ); }) );
补充说明
- 如果你不需要按顺序发起barcode的保存请求,也可以把内层的
concatMap替换为mergeMap实现并行请求,提升处理效率。 - 如果不需要收集所有barcode请求的返回结果,也可以直接用
concat操作符拼接两个流,效果一致。
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

