使用forEach更新MongoDB文档出现MongoExpiredSessionError是什么原因?
问题根因
Array.prototype.forEach 本身是同步执行方法,不支持等待异步回调执行完成。你传入的 async 回调函数返回的 Promise 会被 forEach 直接忽略,不会被外层的 async 函数捕获等待。
这就导致 forEach 遍历触发完所有异步更新请求后,代码会直接进入 finally 块执行 client.close() 关闭数据库连接,此时绝大多数还未执行完成的 updateOne 请求用到的数据库会话已经被销毁,自然抛出 MongoExpiredSessionError 错误。
而普通 for 循环/for...of 循环的 await 是直接写在外层 async 函数的上下文中,每次循环都会等待当前 updateOne 执行完成再进入下一轮,所有更新都跑完后才会执行关闭连接的逻辑,因此运行正常。
修复方案
方案1:并行执行(性能更高)
用 Promise.all 批量等待所有异步更新请求完成,替换原有 forEach 逻辑即可:
// 替换原有forEach代码段 await Promise.all(array.map(async (element) => { return coll.updateOne( { _id: element }, { $set: { mark: "done" } }, { upsert: true } ); }));
所有更新请求会并行发起,全部执行完成后才会继续执行后续关闭连接的逻辑。
方案2:串行执行(和原for循环逻辑一致)
如果需要按数组顺序逐个执行更新,使用for...of循环即可:
// 替换原有forEach代码段 for (const element of array) { await coll.updateOne( { _id: element }, { $set: { mark: "done" } }, { upsert: true } ); }
内容的提问来源于stack exchange,提问作者5inful1
相关产品推荐
相关产品推荐

