You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ionic4:如何等待两个Observable订阅完成后再获取数据

问题分析与解决

你的问题出在两个异步订阅的执行顺序不可控,以及代码里的参数名错误:

  1. 异步执行顺序问题:this.appService.app_data和this.route.queryParams是两个独立的异步流,打开路由时,路由参数的订阅可能先触发,此时this.appService.app_data还未完成加载,值为undefined,调用.questions.find()自然会抛出Cannot read properties of undefined的错误。
  2. 参数名错误:路由参数订阅的参数是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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 13:20:20