You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Lodash each方法中使用Async Await结合Mongoose查询遇空数组问题

问题分析与解决方案

你的问题核心在于 Lodash的_.each是同步迭代工具,它无法处理异步函数返回的Promise,导致你的异步查询还没执行完,console.log(connectionIDs)就已经跑了,所以输出空数组。

为什么原来的写法不行?

_.each会遍历数组里的每个元素,调用你传入的async回调函数,但它完全不会理会这个回调返回的Promise——也就是说,它不会等待每个回调里的await UserProfile.findOne(...)执行完成,就直接继续往下走了。所以当你打印connectionIDs的时候,所有的异步查询都还在pending状态,数组自然是空的。

你提到尝试过await或者Promise.all但没解决,大概率是用法不对,下面给你两种正确的解决思路:


方案1:用for...of循环(串行执行)

for...of是原生支持异步等待的迭代器,它会在每次循环时等待await完成后再进入下一次迭代,能保证顺序执行:

let connectionIDs = [];
// 注意要把这段代码放在async函数里
for (const connection of connections) {
  let id = connection.id;
  let connector = await UserProfile.findOne({phoneNumber: id});
  connectionIDs.push({
    name: connector.name.split(" ")[0],
    imageID: connector.imageID,
    phoneNumber: connector.phoneNumber
  });
}
console.log(connectionIDs); // 现在能拿到正确结果了

方案2:用Promise.all结合Array.map(并行执行,效率更高)

如果你的查询之间没有依赖关系,推荐用这种方式——它会同时发起所有查询,等待全部完成后再处理结果,比串行更快:

// 把每个异步操作转换成Promise
const promises = connections.map(async connection => {
  let id = connection.id;
  let connector = await UserProfile.findOne({phoneNumber: id});
  return {
    name: connector.name.split(" ")[0],
    imageID: connector.imageID,
    phoneNumber: connector.phoneNumber
  };
});

// 等待所有Promise完成,结果会按原数组顺序返回
let connectionIDs = await Promise.all(promises);
console.log(connectionIDs); // 正确结果

关键异步概念理清

  1. async函数的返回值:任何async函数都会返回一个Promise,哪怕你没有显式写return。所以你传给_.each的回调其实是一个个独立的Promise,但_.each不会等待它们。
  2. await的作用范围:await只能在async函数内部生效,而且它只会阻塞当前的async函数上下文,不会影响外部的同步代码。
  3. 同步迭代器vs异步迭代器:像_.each、Array.forEach这类同步迭代器,都不支持处理异步回调的Promise,只有for...of或者专门的异步迭代工具才能正确等待异步操作完成。

内容的提问来源于stack exchange,提问作者Zafta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 10:27:52