JavaScript async/await未按预期执行,Promise resolve前数据提前更新如何修复?
问题根因
Array.prototype.forEach传入async函数时不会等待内部异步逻辑执行完成,就会直接执行后续代码,导致lead.save()在createAutoAccount返回结果前就触发,这是执行顺序不符合预期的核心原因- 原代码中
Lead.findbyid(id)是异步查询方法,缺少await关键字,会导致获取到的lead是Promise实例而非查询结果,后续操作会出现异常
修改方案
将forEach遍历替换为map收集所有异步任务的Promise实例,再通过Promise.all等待所有异步逻辑执行完成后,再执行后续的赋值和保存操作,同时补充缺少的await关键字。
修改后的完整代码
export const update = async (req, res) => { // 补充await获取查询结果,同时修正方法名驼峰写法findById let lead = await Lead.findById(id) let updates = req.body.updates if (updates.clientDetails.alternateContacts && updates.clientDetails.alternateContacts.length > 0) { // 用map收集所有异步处理的Promise const contactProcessTasks = updates.clientDetails.alternateContacts.map(async ele => { if (ele.addedOn) console.log('date exists') else ele.addedOn = new Date() if (ele.email) { console.log('11111111111111111111'); let clientId = await createAutoAccount({ email: ele.email, name:ele.name, contactNumber: ele.phoneNumber }) console.log('22222222222222222222222', clientId); ele.userId = clientId } }) // 等待所有联系人的异步处理逻辑全部执行完成 await Promise.all(contactProcessTasks) lead.clientDetails.alternateContacts = updates.clientDetails.alternateContacts } console.log('update lead') await lead.save(); }
逻辑说明
修改后所有createAutoAccount的异步逻辑都会执行完毕、所有ele.userId都赋值完成后,才会执行lead.clientDetails.alternateContacts的赋值和lead.save()操作,执行顺序就会完全符合预期。
内容的提问来源于stack exchange,提问作者Kunal Arora
相关产品推荐
相关产品推荐

