mongoose中async、await与Promise执行顺序异常问题咨询
问题原因
核心问题是**Array.map不会等待异步回调执行完成**:
- 你在
map里使用async回调函数时,map会直接返回一堆未完成的Promise,但你的代码没有等待这些Promiseresolve,就直接return newNodesArray了。 - 而之前的
const dbNodes = await ...是函数顶层的await,它会阻塞当前函数,直到这个Promise完成后才继续执行下一行;但map里的await只会阻塞单个回调函数,map本身不会暂停等待所有回调完成,导致getNewNodesArray在子查询还没做完时就提前返回了空/不完整的数组,app.post里的res.send也跟着提前执行,后续的nID++和数组push操作完全无效。
解决方案
方案1:用for...of实现串行查询(顺序执行,无并发问题)
适合需要按顺序处理,或者依赖前一个查询结果的场景:
async function getNewNodesArray(level, nID, pdbID) { let newNodesArray = []; const dbNodes = await partsAssemblyModel.find({ParentID:pdbID}).exec(); // 用for...of替代map,确保每个异步操作完成后再执行下一个 for (const dbN of dbNodes) { const dbChildren = await partsAssemblyModel.find({ParentID:dbN.id}).exec(); nID++; const newNode = { id: nID, name: dbN.Description, isParent: dbChildren.length > 0 }; newNodesArray.push(newNode); } return newNodesArray; }
方案2:用Promise.all实现并行查询(效率更高,适合独立查询)
如果子查询之间没有依赖关系,用并行查询可以大幅提升速度,但要注意nID的并发修改问题,建议通过索引生成唯一ID:
async function getNewNodesArray(level, nID, pdbID) { const dbNodes = await partsAssemblyModel.find({ParentID:pdbID}).exec(); // 用map生成所有异步任务的Promise数组,再用Promise.all等待全部完成 const newNodesArray = await Promise.all( dbNodes.map(async (dbN, index) => { const dbChildren = await partsAssemblyModel.find({ParentID:dbN.id}).exec(); // 用索引+初始nID生成唯一id,避免并发修改nID导致重复 const currentId = nID + index + 1; return { id: currentId, name: dbN.Description, isParent: dbChildren.length > 0 }; }) ); return newNodesArray; }
内容的提问来源于stack exchange,提问作者SuperPine
相关产品推荐
相关产品推荐

