Angular 12 如何使用forkJoin等待全部数据请求完成后再执行后续逻辑
问题根源
你之前的修改未生效,核心是两个错误:
fetchListnames方法内直接调用了subscribe,返回的是订阅对象而非可观测流,外部无法感知请求的完成时机- 你需要同时满足所有列表请求完成和路由参数返回两个前提才能执行后续逻辑,需要对两个异步流做组合处理
正确实现方案
第一步:修改列表请求方法,返回Observable流
不要在请求方法内直接订阅,返回forkJoin包装的可观测流即可:
// 泛型内的any可替换为你实际的列表数据类型 fetchLists(): Observable<[any, any, any]> { return forkJoin([ this.httpHandlerCached.getListsA(), this.httpHandlerCached.getListsB(), this.httpHandlerCached.getListsC(), ]); }
第二步:组合异步流,等待所有前置条件完成后执行逻辑
使用combineLatest组合「列表请求流」和「路由参数流」,两个流都返回结果后才会触发回调,确保执行doSomethingWithFetchedLists时数据已经赋值完成:
import { combineLatest } from 'rxjs'; ngOnInit(): void { combineLatest([ this.fetchLists(), this.route.params ]).subscribe(([listsResult, params]) => { // 先赋值列表数据 this.listA = listsResult[0]; this.listB = listsResult[1]; this.listC = listsResult[2]; // 执行后续逻辑,此时所有列表数据已准备完成 this.doSomethingWithFetchedLists(); }); }
优化建议
如果列表请求只需要在组件初始化时执行一次,不需要跟随路由参数变化重复发起,可以对请求流做缓存,避免重复请求:
import { combineLatest, shareReplay } from 'rxjs'; // 缓存请求结果,多次订阅只会发起一次请求 private lists$ = this.fetchLists().pipe(shareReplay(1)); ngOnInit(): void { combineLatest([ this.lists$, this.route.params ]).subscribe(([listsResult, params]) => { this.listA = listsResult[0]; this.listB = listsResult[1]; this.listC = listsResult[2]; this.doSomethingWithFetchedLists(); }); }
注意:请在组件销毁时主动取消订阅,避免内存泄漏,可配合
takeUntil+销毁主题、或者使用async管道在模板中订阅来自动处理。
内容的提问来源于stack exchange,提问作者user16831793
相关产品推荐
相关产品推荐

