如何在async场景下通过.push向数组添加数据并在.map外部读取?
问题分析与解决方案
这个问题我之前也踩过坑,核心是没搞清楚异步函数的执行顺序。咱们来拆解下原因:
你在map里用了async回调函数,这意味着devPre.map(...)返回的其实是一个Promise数组,而不是直接执行完所有异步操作。你的外部console.log(cod)是同步代码,会在所有await models.pres.findOne的异步请求完成前就执行,这时候cod数组自然是空的。
下面给你两种靠谱的解决方案:
方案1:用Promise.all优雅处理(推荐)
这种方式会并行发起所有异步请求,效率更高,而且不需要手动push值到数组:
// 把每个异步操作的结果直接返回,map会生成Promise数组 const promiseArray = devPre.map(async (item) => { const pre = await models.pres.findOne({ where: { id: item.pres_id } }); return pre.codPre; }); // 等待所有Promise完成,自动把结果组装成数组 const cod = await Promise.all(promiseArray); console.log(cod); // 这里就能拿到完整的结果数组了
注意:这段代码需要放在async函数内部执行,因为用了await。
方案2:用for...of顺序执行异步操作
如果你的业务需要按顺序发起请求(比如前一个请求完成再发下一个),可以用for...of代替map:
async function fetchCodigos() { let cod = []; for (const item of devPre) { const pre = await models.pres.findOne({ where: { id: item.pres_id } }); cod.push(pre.codPre); } console.log(cod); // 内部能拿到正确结果 return cod; } // 外部调用时,通过then或者await获取结果 fetchCodigos().then((result) => { console.log(result); // 外部也能拿到正确数组 });
关键提醒
async函数的本质是返回Promise,所以map里用async回调时,不要误以为它会同步执行完所有逻辑。- 所有依赖异步操作结果的代码,都要放在
await或者.then()的回调里,确保异步操作完成后再执行。
内容的提问来源于stack exchange,提问作者JimmyWj4EHiM
相关产品推荐
相关产品推荐

