如何使用RxJS的Observable实现多个请求按调用顺序依次执行?
RxJS 顺序执行请求实现方案
要实现按调用顺序等待前一个请求完成再发起下一个请求,使用 RxJS 的 concat 操作符即可实现,这是 RxJS 处理串行异步任务的标准方案,具体实现如下:
步骤1:改造 makeRequest 方法
调整方法逻辑,仅返回 Observable 实例,将副作用逻辑放到管道内处理,不要在方法内部直接订阅:
import { tap, catchError } from 'rxjs/operators'; import { of } from 'rxjs'; makeRequest() { return this.getAuctionService.getAllAuctionsUsingPOST(params).pipe( // 处理请求成功后的业务逻辑 tap((response: any) => { this.filterService.auctionTotalPages = response.totalPages; this.currentPage = response.currentPage; this.remapLazyLoadedData(response, cb); }), // 捕获请求错误,处理异常提示 catchError((error) => { this.toastr.error(error.error.description, error.error.error); // 若希望某一个请求出错后仍执行后续请求,返回空Observable return of(null); // 若希望出错后立刻终止后续请求,替换为以下代码 // return throwError(() => error); }) ) }
步骤2:改造 onButtonClick 方法
使用 concat 操作符按顺序组装所有请求Observable,统一订阅即可:
import { concat } from 'rxjs'; onButtonClick() { // concat会按传入顺序订阅Observable,前一个请求完成后才会发起下一个 concat( this.makeRequest(), this.makeRequest(), this.makeRequest(), this.makeRequest() ).subscribe() }
原理解释
你之前直接调用.subscribe()没有生效的原因是:Observable 是懒执行的,每次调用subscribe会立刻触发请求执行,没有统一的调度逻辑自然就是并行的。
而concat操作符会管理所有传入的Observable的订阅时机,只有前一个Observable正常完成(complete)之后,才会订阅下一个Observable,天然保证了请求的发送顺序和响应顺序完全一致。
如果是动态数量的请求,只需要把所有请求的Observable实例放到数组中,传入concat即可:concat(...requestList).subscribe()。
如果需要在所有请求全部完成后执行额外逻辑,可以在concat的管道中添加finalize操作符处理即可。
内容的提问来源于stack exchange,提问作者peckoski
相关产品推荐
相关产品推荐

