Node.js搭配MongoDB使用async forEach执行array.push不生效问题
问题原因
Array.forEach方法不支持等待异步回调执行完成,你传入的异步回调会立刻返回 Promise 实例,但 forEach 本身不会收集这些 Promise,也不会等待它们状态变更,就直接结束遍历流程。- 你在 forEach 外层添加的
await是无效的,因为 forEach 的返回值是undefined而非可等待的 Promise 对象,因此代码会直接执行到后续打印/返回info数组的逻辑,此时所有数据库查询操作还未执行完成,数组自然为空。 - 代码中
await info.push(matchinfo)的写法也存在冗余,数组 push 是同步操作,不需要添加 await 等待。
解决方案
有两种常用的修复方案:
方案1:使用Promise.all并发查询(性能更高)
将数组遍历改为 map 方法,把每个日期对应的查询请求映射为 Promise 实例,再通过 Promise.all 等待所有请求完成:
getWeekOldMatches = async() => { const dates = await getDatesRelative(-7); const db = await database.db(); // 批量等待所有异步查询完成 const info = await Promise.all(dates.map(async (date) => { return database.query(db, "highlight", {"matchDetail.matchSummary.localStartDate": date}); })); console.log(info); return info; }
方案2:使用for...of循环串行查询(适用于需要控制并发的场景)
如果需要避免同时发起过多数据库请求,可以用支持异步等待的 for...of 循环替代 forEach:
getWeekOldMatches = async() => { const dates = await getDatesRelative(-7); const info = []; const db = await database.db(); for (const date of dates) { const matchinfo = await database.query(db, "highlight", {"matchDetail.matchSummary.localStartDate": date}); info.push(matchinfo); } console.log(info); return info; }
内容的提问来源于stack exchange,提问作者Deepak Kumar Yadav
相关产品推荐
相关产品推荐

