MongoDB查询中async await使用不当导致taskDetails为空
问题根因
你遇到的taskDetails返回空数组问题确实是异步逻辑编写错误导致,核心问题有3点:
Array.map()返回值是由内部执行结果组成的数组,直接对数组使用await不会等待内部数据库查询逻辑执行完成,await仅对单个Promise生效- 你使用了
exec()的回调写法,没有将数据库查询包装为可等待的Promise,响应发送时所有查询逻辑还没执行完 - 代码中没有提前初始化
tasksDetails数组,直接执行push操作存在隐式报错风险 - 循环内逐个查询单条任务属于典型的N+1查询问题,数据量大时接口性能会非常差。
最优修复方案
直接使用MongoDB的$in操作符一次性查询所有关联任务,从根源避免循环异步问题,同时查询性能更高:
exports.getSingleProject = async (req, res) => { req.project.logo = undefined; // 提前初始化任务详情数组 req.project.tasksDetails = []; // 仅当项目存在关联任务时执行查询 if (req.project.tasks?.length) { req.project.tasksDetails = await taskSchema.find({ _id: { $in: req.project.tasks } }); } responseMessages( res, 200, true, "Single project fetched successfully.", req.project ); };
循环写法的修正(不推荐)
如果有特殊场景必须循环单条查询,需要用Promise.all包裹所有查询Promise,确保所有查询执行完成后再发送响应:
exports.getSingleProject = async (req, res) => { req.project.logo = undefined; req.project.tasksDetails = []; await Promise.all( req.project.tasks.map(async (taskItem) => { const task = await taskSchema.findById(taskItem.toString()); req.project.tasksDetails.push(task); }) ); responseMessages( res, 200, true, "Single project fetched successfully.", req.project ); };
内容的提问来源于stack exchange,提问作者piupaul
相关产品推荐
相关产品推荐

