Mongoose路由中如何等待函数及其内部所有异步逻辑执行完成?
问题原因
- 核心问题出在
forEach方法不支持异步等待:你在forEach的回调中写的await User.findById不会阻塞外层函数执行,func1会在遍历发起所有用户查询请求后立刻执行回调返回响应,此时大部分查询还没返回结果,questionsToSend自然还没填充完成。 - 代码混用
async/await和回调嵌套逻辑,没有利用异步语法的特性管控时序。 - 你当前代码中推入数组的用户信息键名为
askedUserData,和你需要的askedBy字段不符,会导致最终响应结构不符合预期。
修复方案
直接用async/await + Promise.all管控所有异步操作时序,修改后代码如下:
const _ = require('lodash') // 确保已引入你用到的lodash依赖 router.get("/questions", async (req, res) => { try { if (!req.query.forumTab) return res.status(400).send("something went wrong"); const page = parseInt(req.query.page) - 1; const perPage = parseInt(req.query.perPage); // 第一步查询问题列表 const questions = await Question.find({ forumTab: req.query.forumTab }) .sort({ askedAt: -1 }) .limit(perPage) .skip(perPage * page); console.log("xxxxxxx"); // 第二步并行查询所有用户信息,等待全部请求完成再处理 const questionsToSend = (await Promise.all(questions.map(async (question) => { const askedBy = await User.findById(question.askedBy._id); // 过滤掉用户不存在的问题 if (!askedBy) return null; // 组装符合要求的响应结构 return { ..._.pick(question, [ "_id", "title", "forumTab", "askedAt", "tags", ]), askedBy } }))).filter(Boolean); console.log("yyyyyyyy"); res.status(200).send(questionsToSend); } catch (err) { console.error(err); res.status(500).send("server error"); } });
改动说明
- 去掉了冗余的回调嵌套,直接用
async/await按顺序执行查询逻辑,时序更可控 - 用
map+Promise.all并行发起所有用户查询请求,比串行查询效率更高,且会等待所有异步任务执行完成后再处理结果 - 调整了返回字段的键名为
askedBy,完全匹配你要求的响应结构 - 增加了全局异常捕获逻辑,避免数据库查询报错导致接口无响应
内容的提问来源于stack exchange,提问作者Rishav Raj
相关产品推荐
相关产品推荐

