Mongoose中async/await使用问题:遍历文档及判断作者关注状态
Mongoose中async/await使用问题解决方案
你的代码问题根源
你这段代码的核心问题是:当Post.find().exec()传入回调函数时,它不会返回Promise,外部的await完全不起作用——这就是VS Code提示的原因。而且回调里的return doc也无法传递到外部的post变量,异步回调的返回值不会被外部捕获。
需求实现的正确方式
要完成「查询最多10条帖子,判断每条帖子作者是否被指定用户关注」的需求,推荐两种可靠实现:
方式1:先查帖再逐个验证(async/await遍历)
async function index(req, res) { try { const { user_id } = req.body; // 查询最多10条帖子 const posts = await Post.find().limit(10).exec(); // 遍历帖子,给每条添加关注状态 const postsWithFollowStatus = await Promise.all(posts.map(async (post) => { // 注意:这里whom_id应该是帖子的作者ID,不是帖子ID,你原代码的doc._id是笔误 const followRecord = await Follows.findOne({ who_id: user_id, whom_id: post.author_id }); // 把Mongoose文档转成普通对象,添加isFollowing字段 return { ...post.toObject(), isFollowing: !!followRecord // 存在关注记录则为true }; })); // 若只需要返回已关注作者的帖子,可加过滤 // const filteredPosts = postsWithFollowStatus.filter(post => post.isFollowing); res.json(postsWithFollowStatus); } catch (err) { res.status(500).json({ error: err.message }); } }
方式2:聚合查询(更高效,减少数据库请求)
如果数据量较大,逐个查询会产生N+1次数据库请求,用聚合可以一次性完成所有操作:
async function index(req, res) { try { const { user_id } = req.body; const posts = await Post.aggregate([ // 限制最多10条帖子 { $limit: 10 }, // 关联follows集合,匹配当前用户的关注记录 { $lookup: { from: "follows", localField: "author_id", // 帖子的作者ID字段 foreignField: "whom_id", as: "followInfo", pipeline: [{ $match: { who_id: user_id } }] } }, // 生成isFollowing字段 { $addFields: { isFollowing: { $gt: [{ $size: "$followInfo" }, 0] } } }, // 移除不需要的中间字段 { $unset: "followInfo" } ]); res.json(posts); } catch (err) { res.status(500).json({ error: err.message }); } }
Mongoose用async/await遍历文档的通用方法
遍历文档并执行异步操作的核心逻辑:
- 先用
await获取完整的文档数组 - 并行处理用
Promise.all()+map(),顺序处理用for...of循环:
// 顺序执行示例 async function processDocs() { const docs = await SomeModel.find().exec(); for (const doc of docs) { // 对每个文档执行异步操作,按顺序完成 await someAsyncFunction(doc); } }
内容的提问来源于stack exchange,提问作者Nihat Abdullazade
相关产品推荐
相关产品推荐

