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

Node.js中async异步函数返回数组为空或值为undefined问题求解

问题原因说明

第一种写法返回空数组的原因

  • JS内置的Array.prototype.forEach是同步迭代方法,本身不会返回Promise,你在它前面加await没有任何作用,执行完forEach会直接走到后续的打印和返回逻辑,此时内部所有User.findById的异步查询还没有执行完成,.then回调还没触发,所以emailList还是空数组。

第二种写法元素全为undefined的原因

  • User.findById是Mongoose提供的异步查询方法,调用后返回的是Pending状态的Promise实例,而非直接返回查询结果。你没有加await就直接读取workerEmail属性,Promise实例上不存在该属性,自然只能拿到undefined,存入数组的全是undefined。

和Python控制流的差异说明

Python的异步迭代有async for等原生语法支持,内部会自动等待异步任务完成,但JS的常规数组迭代方法(forEach/for in等)都没有内置异步支持,不会等待你传入的异步回调执行完成,有Python开发背景很容易踩这个坑。

正确实现方式

推荐使用Promise.all搭配map来实现批量异步查询的等待,所有异步查询完成后会自动组装成结果数组:

exports.getUserEmailByAccess = async (moduleType) => {
  const foundUsers = await Access.find({moduleType: moduleType})
  console.log(foundUsers);

  const emailList = await Promise.all(
    foundUsers.map(async access => {
      const foundUser = await User.findById(access.userId)
      console.log(foundUser.workerEmail)
      return foundUser.workerEmail
    })
  )

  console.log(emailList)
  return emailList
}

如果需要按顺序串行查询而非并行,也可以用常规的for of循环,它支持内部的await等待:

exports.getUserEmailByAccess = async (moduleType) => {
  let emailList = []
  const foundUsers = await Access.find({moduleType: moduleType})
  console.log(foundUsers);

  for (const access of foundUsers) {
    const foundUser = await User.findById(access.userId)
    console.log(foundUser.workerEmail)
    emailList.push(foundUser.workerEmail)
  }

  console.log(emailList)
  return emailList
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 01:57:03