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
相关产品推荐
相关产品推荐

