JS异步问题:如何让类方法等待构造函数异步任务完成后执行
问题根因
你代码的核心错误出在构造函数内的map回调逻辑:你使用了带花括号的箭头函数,但没有显式返回myAsyncCall生成的Promise实例,导致Promise.all接收的是3个undefined元素组成的数组。Promise.all处理非Promise类型值时会直接判定为 fulfilled 状态,因此await this.ready不会等待异步操作完成,直接执行了后续的console.log('myFunction1'),最终出现输出顺序不符合预期的问题。
修复方案
仅需要修改构造函数内map的回调写法,保证返回每个异步调用的Promise实例即可,同时如果需要myFunction2也满足执行前提,可参照myFunction1的逻辑改造:
// 不可修改区域开始 //=================== function notifyUrls(item, callback) { asyncOperation(item).then((res) => { callback(res); }); } //=================== // 不可修改区域结束 const asyncOperation = () => { return new Promise((resolve, reject) => { setTimeout(() => { console.log('Timeout execute'); resolve(); }, 2000); }); }; const URL1 = 'http://www.somerestapi/get1'; const URL2 = 'http://www.somerestapi/get2'; const URL3 = 'http://www.somerestapi/get3'; class MyClass { constructor() { // 修复点:map回调保证返回Promise实例,以下两种写法二选一即可 // 写法1:去掉花括号,箭头函数隐式返回 this.ready = Promise.all([URL1, URL2, URL3].map(url => this.myAsyncCall(url))); // 写法2:保留花括号,显式return // this.ready = Promise.all([URL1, URL2, URL3].map(url => { return this.myAsyncCall(url); })); } myAsyncCall(item) { return new Promise((resolve, reject) => { notifyUrls(item, (res) => { resolve(res); }); }); } async myFunction1() { await this.ready; // 仅在构造函数完成通知操作后执行 // ... console.log('myFunction1'); } // myFunction2如果也需要满足执行前提,同改造为async方法等待this.ready async myFunction2() { await this.ready; // 仅在构造函数完成通知操作后执行 // ... console.log('myFunction2'); } } (async () => { const myClass = new MyClass(); await myClass.myFunction1(); })();
运行验证
修复后运行代码,会等待2秒先输出3次Timeout execute,再输出myFunction1,完全符合预期输出顺序。
内容的提问来源于stack exchange,提问作者Or Assayag
相关产品推荐
相关产品推荐

