Ionic4:如何等待两个Observable订阅完成后再获取数据
问题分析与解决
你的问题出在两个异步订阅的执行顺序不可控,以及代码里的参数名错误:
- 异步执行顺序问题:
this.appService.app_data和this.route.queryParams是两个独立的异步流,打开路由时,路由参数的订阅可能先触发,此时this.appService.app_data还未完成加载,值为undefined,调用.questions.find()自然会抛出Cannot read properties of undefined的错误。 - 参数名错误:路由参数订阅的参数是
p,但你在内部写了params.id,这里params并未定义,即使app_data加载完成,这行代码也会报错。
解决方法
方法一:合并两个异步流(推荐)
使用RxJS的combineLatest,确保两个数据都准备好后再执行查找逻辑:
import { combineLatest } from 'rxjs'; // ... app_data: AppData; question: Question; ngOnInit() { combineLatest([ this.appService.app_data, this.route.queryParams ]).subscribe(([appData, params]) => { this.app_data = appData; this.question = appData.questions.find(i => i.id === params.id); }); }
方法二:添加加载状态判断
在路由参数订阅里先检查app_data是否已加载,同时修正参数名:
app_data: AppData; question: Question; ngOnInit() { this.appService.app_data.subscribe((v) => { this.app_data = v; // 数据加载完成后,同步当前路由参数对应的问题 const currentParams = this.route.snapshot.queryParams; if (currentParams.id) { this.question = v.questions.find(i => i.id === currentParams.id); } }); this.route.queryParams.subscribe(p => { // 先确认app_data和questions已存在 if (this.app_data?.questions) { this.question = this.app_data.questions.find(i => i.id === p.id); } }); }
方法三:用switchMap等待数据加载
先等待app_data加载完成,再监听路由参数变化:
import { switchMap } from 'rxjs/operators'; // ... app_data: AppData; question: Question; ngOnInit() { this.appService.app_data.pipe( switchMap(appData => { this.app_data = appData; return this.route.queryParams; }) ).subscribe(params => { this.question = this.app_data.questions.find(i => i.id === params.id); }); }
内容的提问来源于stack exchange,提问作者anderlaini
相关产品推荐
相关产品推荐

