Async/Await循环插入数据失效,请求技术排查与解决
问题分析与修复方案
看起来你在批量插入通知记录时遇到了异步处理的问题,核心问题出在Mongoose的save方法与回调/await的混用,以及错误收集逻辑上。我们一步步来拆解和修复:
你的代码存在的问题
save方法的错误用法:你同时使用了await和回调函数,但Mongoose的save如果传入回调,就不会返回Promise,这意味着await根本不会等待保存操作完成,Promise.all会提前结束,导致后续的callback可能在所有记录还没保存完就执行了。- 错误收集不可靠:因为回调函数的执行时机不受
await控制,_err数组的错误收集可能不完整,甚至完全收集不到错误。
修复后的代码
exports.notificationAdd = async function(req, callback) { const notifications = req.notifications; const errors = []; await Promise.all(notifications.map(async (notification) => { try { const schemaObj = new NotificationSchema(notification); await schemaObj.save(); // 改用Promise形式,去掉回调 } catch (err) { errors.push(err); } })); if (errors.length > 0) { callback({ code: 400, status: 'error', message: "Unable to add notifications: " + errors.map(e => e.message).join(', ') }); } else { // 补充成功回调逻辑,避免调用方一直等待响应 callback({ code: 200, status: 'success', message: "Notifications added successfully" }); } };
关键改进点
- 用Promise风格替代回调:Mongoose的所有CRUD方法都支持Promise,直接
await schemaObj.save()即可等待保存完成,不需要回调。 try/catch捕获单个错误:在map的异步函数内部用try/catch捕获每个保存操作的错误,确保一个记录保存失败不会影响其他记录,同时能把错误完整收集到数组里。- 完善成功回调:你原来的代码只处理了错误情况,补充成功时的回调逻辑能让调用方正常接收结果。
额外优化建议
如果你的Mongoose版本支持,还可以用NotificationSchema.insertMany()来批量插入,这比循环调用save更高效:
exports.notificationAdd = async function(req, callback) { try { await NotificationSchema.insertMany(req.notifications); callback({ code: 200, status: 'success', message: "Notifications added successfully" }); } catch (err) { callback({ code: 400, status: 'error', message: "Unable to add notifications: " + err.message }); } };
insertMany会一次性插入所有文档,性能更好,而且如果有错误会统一抛出。不过要注意:如果需要对每个文档做单独的预处理,那循环save更合适;如果只是单纯批量插入,insertMany是最优选择。
内容的提问来源于stack exchange,提问作者Diptesh Atha
相关产品推荐
相关产品推荐

