Node.js如何async/await并行执行多个MongoDB findOne异步请求
问题原因
你自己编写的Promise并行实现无法正常工作,核心问题有三个:
- 传入
new Promise()的执行函数没有调用resolve()或reject(),外层的await会永久处于挂起状态,永远不会继续执行后续逻辑 - 直接赋值
findOne()返回值的写法虽然会让三个查询请求并行发起,但没有等待三个Promise状态落定的逻辑,执行到打印语句时,三个变量大概率还是处于pending状态的Promise对象,拿不到实际的查询文档数据 - 代码里的
collection_1/2/3没有提前声明,严格模式下会直接抛出引用错误
你最初的串行写法总耗时是三个查询耗时的总和,因为必须等前一个查询完全返回才会发起下一个查询,性能损耗非常明显。
正确实现方案
直接使用JavaScript原生提供的Promise.all()方法即可,这是处理多个异步任务并行执行、统一等待结果的标准实现:
- 三个
findOne调用会立刻发起请求,不会互相阻塞等待 - 总耗时取决于三个查询中最慢的那一个,相比串行性能提升明显
- 最终返回的结果顺序和传入的Promise数组顺序完全一致,不会因为请求返回先后出现乱序
- 默认行为和串行写法一致:任意一个查询报错,整个
Promise.all会立刻抛出异常,进入异常处理逻辑
标准写法示例:
async function myFunction() { // 同时发起三个集合的查询请求 const queryTasks = [ firstCollection.findOne({}), secondCollection.findOne({}), thirdCollection.findOne({}) ] // 等待所有查询全部完成,解构拿到对应结果 const [collection_1, collection_2, collection_3] = await Promise.all(queryTasks) console.log(collection_1, collection_2, collection_3) }
特殊场景适配
如果你的业务场景允许单个集合查询失败,不希望某一个查询报错就阻断所有结果的获取,可以替换为Promise.allSettled(),它会等待所有查询都执行完成(不管成功还是失败),再返回每个任务的执行状态和结果:
async function myFunction() { const queryTasks = [ firstCollection.findOne({}), secondCollection.findOne({}), thirdCollection.findOne({}) ] const results = await Promise.allSettled(queryTasks) // 按需处理每个结果,失败时可以给默认值 const collection_1 = results[0].status === 'fulfilled' ? results[0].value : null const collection_2 = results[1].status === 'fulfilled' ? results[1].value : null const collection_3 = results[2].status === 'fulfilled' ? results[2].value : null console.log(collection_1, collection_2, collection_3) }
内容的提问来源于stack exchange,提问作者Burnsy
相关产品推荐
相关产品推荐

