在mongosh中能否使用Promises或async/await保证任务同步执行?
mongosh执行顺序控制方案
问题原因
mongosh完全支持Promise和async/await做执行顺序控制,你遇到的乱序问题是两个原因导致的:
- 所有mongodb操作方法默认返回异步Promise,不加
await的话不会等待操作完成就会直接执行后续代码 - 普通的
Array.prototype.forEach不支持等待异步回调执行完成,就算回调内加了await,forEach也会直接结束,触发后续逻辑
解决方案
方案1:使用for...of循环等待所有异步操作完成
替换forEach为支持异步等待的for...of循环,所有数据库操作前加await即可保证执行顺序:
// mongosh 支持顶层await,可直接编写如下逻辑无需额外async包裹 // 步骤1:查询所有客户端并插入地址 const clients = await db.clients.find({}).toArray(); for (const client of clients) { // 等待本次插入完成再执行下一次循环 await db.addresses.insertMany([ { // 你的地址文档字段示例 clientId: client._id, address: client.address } ]); } // 步骤2:步骤1所有插入完成后才会执行 const addresses = await db.addresses.find({}).toArray(); for (const addr of addresses) { // 你的地址处理逻辑 }
方案2:批量操作优化性能(推荐)
如果不需要单条 client 插入后做特殊处理,可先收集所有待插入的地址,一次性批量插入,IO效率更高:
// 1. 收集所有待插入地址 const clients = await db.clients.find({}).toArray(); const insertDocs = clients.map(client => ({ clientId: client._id, // 其他字段 })); // 2. 等待批量插入完成 await db.addresses.insertMany(insertDocs); // 3. 插入完成后再执行后续查询逻辑 const allAddresses = await db.addresses.find({}).toArray(); // 处理地址逻辑
注意事项
- 所有数据库操作方法(find、insertMany、updateOne等)都必须加
await,才会阻塞等待操作完成 - 不要在forEach、map等数组方法的回调中直接编写异步逻辑不做统一等待,这类方法不会等待异步回调执行完成
- mongosh v1.0及以上版本默认支持顶层await,无需额外用async函数包裹脚本逻辑
内容的提问来源于stack exchange,提问作者cierech
相关产品推荐
相关产品推荐

