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

MongoDB双集合查询时,async函数提前返回空数组问题

解决MongoDB关联集合查询时async/await导致返回空数组的问题

问题核心是forEach不支持async/await的异步等待:forEach会同步遍历数组,内部的async回调会变成独立的Promise,但forEach不会等待这些Promise执行完成,所以getCommentDetails会直接返回初始的空数组,等后续异步操作完成时,函数早已返回。

下面提供两种可行的解决方案:

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

把forEach替换为for...of循环,它能原生支持await等待,确保每一步异步操作完成后再进行下一次循环,所有数据都存入数组后再返回:

const getCommentDetails = async (id) => {
  const commentDetails = [];

  const comments = await commentsCollection
    .find({ complain_id: id })
    .toArray();

  // 用for...of替代forEach,支持await等待异步操作完成
  for (const comment of comments) {
    const user = await usersCollection.findOne({
      _id: ObjectId(comment.user_id),
    });

    commentDetails.push({
      _id: comment._id,
      complainId: comment.complain_id,
      userId: comment.user_id,
      comment: comment.comment,
      name: user.name,
      date: comment.createdAt,
    });
  }

  return commentDetails;
};

方案2:使用Promise.all并行请求(效率更高)

如果不需要严格串行执行查询,可通过map将每个评论的处理逻辑转为Promise,再用Promise.all等待所有Promise完成,这样所有用户查询会并行执行,性能更优:

const getCommentDetails = async (id) => {
  const comments = await commentsCollection
    .find({ complain_id: id })
    .toArray();

  // 将每个评论的处理逻辑转为Promise,并行执行所有异步操作
  const commentDetails = await Promise.all(comments.map(async (comment) => {
    const user = await usersCollection.findOne({
      _id: ObjectId(comment.user_id),
    });

    return {
      _id: comment._id,
      complainId: comment.complain_id,
      userId: comment.user_id,
      comment: comment.comment,
      name: user.name,
      date: comment.createdAt,
    };
  }));

  return commentDetails;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 22:55:18