Ionic中TypeScript异步函数数据加载时序问题咨询
解决Ionic中异步加载数据后无法立即使用的问题
你遇到的是很典型的异步操作时序问题——testFunc里的this.papersData.getPaper().subscribe()是异步执行的,当你在loadPaper里调用testFunc()之后,代码会立刻继续执行后面的console.log和页面跳转,但这时候异步请求还没完成,this.questions自然还没被赋值。
下面给你几种常用的解决思路:
方案一:把后续逻辑移到异步回调内部(最直接)
既然数据要等异步请求完成才能拿到,那我们就把依赖这个数据的操作都放到subscribe的回调里,确保执行顺序正确:
loadPaper(paper){ this.papersData.getPaper().subscribe(questions => { this.questions = questions.questions; // 现在数据已经加载完成,再执行后续操作 console.log('questions', this.questions); console.log('paper', paper); this.navCtrl.push(this.loadPaperPage, { paper: paper, questions: this.questions }); }, error => { // 别忘了处理请求失败的情况 console.error('加载试卷数据失败', error); }); } // 如果testFunc没有其他复用场景,可以直接去掉它
方案二:让testFunc返回Observable,在loadPaper中订阅
如果想保留testFunc的复用性,可以让它返回请求的Observable,然后在loadPaper里订阅并处理后续逻辑:
loadPaper(paper){ this.testFunc().subscribe( questionsData => { this.questions = questionsData.questions; console.log('questions', this.questions); console.log('paper', paper); this.navCtrl.push(this.loadPaperPage, { paper: paper, questions: this.questions }); }, error => { console.error('加载数据出错', error); } ); } testFunc(){ // 返回Observable供外部订阅 return this.papersData.getPaper(); }
方案三:用async/await简化异步流程(更符合同步思维)
如果你习惯同步风格的代码,可以把Observable转换成Promise,然后用async/await来写:
async loadPaper(paper){ try { // 将Observable转为Promise,等待请求完成 const questionsData = await this.papersData.getPaper().toPromise(); this.questions = questionsData.questions; console.log('questions', this.questions); console.log('paper', paper); this.navCtrl.push(this.loadPaperPage, { paper: paper, questions: this.questions }); } catch (error) { console.error('加载试卷失败', error); } } // 若testFunc需要复用: testFunc(){ return this.papersData.getPaper().toPromise(); }
核心要点就是:异步操作的结果不能被同步代码直接使用,必须等待异步任务完成(通过回调、订阅、await等方式)后,再执行依赖该结果的代码。
内容的提问来源于stack exchange,提问作者sisko
相关产品推荐
相关产品推荐

