使用async/await与Promise.all时遇延迟await未等待的问题
问题分析与解决
核心问题
当你在getAllTheWeeks中加入setTimeout模拟延迟时,若未将setTimeout正确包裹为Promise,async函数会在触发setTimeout后直接返回已解决的Promise,导致initUsersCourse中的await this.getAllTheWeeks()未等待延迟操作完成就继续执行后续代码。
另外原代码存在冗余操作:Array.push()是同步方法,await this.allOfTheWeeks.push(w)毫无意义;Promise.all包裹这类同步操作的async函数也完全多余。
修正后的代码
优化后的getAllTheUnits和getAllTheWeeks
async getAllTheUnits() { console.log('allunits called 1') let unitRef = db.collection('units') try { let allUnitsSnapShot = await unitRef.get() // 直接遍历快照收集数据,无需Promise.all和多余await this.allOfTheUnits = allUnitsSnapShot.docs.map(doc => { let u = doc.data() u.id = doc.id return u }) console.log('allunits called 2 ', this.allOfTheUnits.length) } catch (err) { console.log('Error getting all the units', err); } }, async getAllTheWeeks() { console.log('allweeks called 1') let weekRef = db.collection('weeks') try { let allWeeksSnapShot = await weekRef.get() // 将setTimeout包装为Promise,确保await能等待延迟完成 await new Promise(resolve => setTimeout(resolve, 1000)) this.allOfTheWeeks = allWeeksSnapShot.docs.map(doc => { let w = doc.data() w.id = doc.id return w }) console.log('allweeks called 2 ', this.allOfTheWeeks.length) } catch (err) { console.log('Error getting all the weeks', err); } },
调用函数无需修改
async initUsersCourse() { console.log('1') await this.getAllTheUnits() await this.getAllTheWeeks() console.log('2') const allUnits = this.allOfTheUnits const allWeeks = this.allOfTheWeeks console.log('3') console.log('allUnits ', Array.isArray(allUnits), allUnits.length) console.log('allWeeks ', Array.isArray(allWeeks), allWeeks.length) }
关键说明
- 包装setTimeout为Promise:
await new Promise(resolve => setTimeout(resolve, 1000))让async函数等待延迟结束后再继续执行后续逻辑,确保initUsersCourse中的await能正确等待。 - 移除冗余异步操作:直接用
map将文档数据转换为数组赋值给实例变量,比逐个push更高效,也避免了无意义的Promise.all和await。
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

