Angular如何等待多个异步函数全部执行完成后再调用后续函数
问题根因
你的5个接口请求都是异步RxJS流,subscribe回调仅在接口响应后才会执行,而ngOnInit内的代码是同步顺序执行的:调用完5个接口请求方法后会立刻执行patchFormValue,此时接口尚未返回响应,对应的全局存储变量(titleData/nationData等)均为初始空值,因此首次执行时if判断不通过,表单赋值逻辑不触发;第二次执行时上一轮的接口已经返回结果,变量已赋值,所以可以正常执行。
改造方案
采用RxJS的forkJoin操作符实现“多个异步流全部完成后再执行后续逻辑”的需求,改造步骤如下:
- 改造5个接口请求方法,去掉内部的subscribe逻辑,返回Observable对象供上层组合
- 在
ngOnInit中用forkJoin组合5个请求,统一订阅后再执行表单赋值逻辑
改造后代码示例
1. 接口请求方法改造(以getTitle为例,其余4个方法同理改造)
private getTitle(): Observable<any> { // 可替换any为你接口返回的实际类型 return this._addNewPassengerService.getTitle() .pipe(takeUntil(this.componentDestroyed$)); } // getNation、getGender、getPass、getPax按相同逻辑修改,返回对应的Observable
2. ngOnInit逻辑改造
ngOnInit() { forkJoin({ titleData: this.getTitle(), nationData: this.getNation(), genderData: this.getGender(), passengerData: this.getPass(), paxData: this.getPax() }).pipe(takeUntil(this.componentDestroyed$)) .subscribe(res => { // 所有接口都返回结果后才会进入此回调 this.titleData = res.titleData || []; this.nationData = res.nationData || []; this.genderData = res.genderData || []; this.passengerData = res.passengerData || []; this.paxData = res.paxData || []; this._changeDetector.detectChanges(); // 执行表单赋值 this.patchFormValue(); }) }
3. patchFormValue可保留原有逻辑
private patchFormValue() { const data = this.data.passengerDetails; if (data && this.titleData && this.nationData && this.paxData && this.genderData && this.passengerData) { this.addPassengersFormGroup.controls.passengerFormArray['controls'].forEach(group => { group.patchValue(data); }); this._changeDetector.detectChanges(); } }
注意事项
forkJoin仅会在所有传入的Observable都完成(complete)后才触发一次回调,Angular HttpClient返回的HTTP请求Observable在请求完成后会自动complete,符合该操作符的使用条件- 若需要兼容单个请求失败不影响其他请求的场景,可给每个Observable增加
catchError容错处理,示例:this.getTitle().pipe(catchError(err => of([]))),单个请求失败时会返回默认空值,不会导致整个forkJoin终止
内容的提问来源于stack exchange,提问作者KillMonger
相关产品推荐
相关产品推荐

