JavaScript中forEach循环如何等待Promise执行?MongoDB场景问题求解
问题原因
- 你代码里的
db.collection.count是异步操作,返回的是Promise对象,forEach方法不会等待这些异步任务执行完成,会直接完成遍历执行后续的return arr逻辑 - 此时所有的count查询还在后台执行,等你执行
res.success(arr)的时候,cur.prop = retrieved的赋值逻辑根本还没跑,所以返回的是未修改的原始数组
解决方法
把forEach循环替换成map收集所有异步Promise,用Promise.all等待所有异步操作执行完成后再返回结果。修改后的代码如下:
db.collection("collection") .find() .toArray() .then((arr) => { // 用map收集所有count查询的Promise const countPromises = arr.map(cur => { return db.collection("another-collection") .count({key: cur.prop}) .then((retrieved) => { cur.prop = retrieved; }) .catch((err) => { // 处理单条查询的错误,比如可以给cur.prop设默认值 cur.prop = 0; console.error('查询失败:', err); }); }); // 等待所有count查询执行完成后再返回处理后的数组 return Promise.all(countPromises).then(() => arr); }) .then(arr => { res.success(arr); }) .catch((err) => { // 处理整体错误 console.error('整体流程错误:', err); res.error(err); });
如果用async/await写法可读性会更高,示例如下:
try { const arr = await db.collection("collection").find().toArray(); await Promise.all(arr.map(async cur => { const retrieved = await db.collection("another-collection").count({key: cur.prop}); cur.prop = retrieved; })); res.success(arr); } catch (err) { // 处理错误 console.error(err); res.error(err); }
内容的提问来源于stack exchange,提问作者D. Albert
相关产品推荐
相关产品推荐

