Node.js中在Model.create()回调内调用findOneAndUpdate不生效如何解决
问题原因分析
- 未获取创建成功的文档ID:
Bills.create执行成功后生成的文档完整数据会通过回调的第二个参数返回,你当前代码使用的入参b中的_id是未赋值状态(默认MongoDB会在文档插入时生成_id,不会主动写入你传入的参数对象b中),所以更新操作传入的id_fatturazione值无效,就算更新执行也不会有预期效果。 - 异步时序错误:
findOneAndUpdate是异步IO操作,你没有等待该操作执行完成就调用了resolve(),外层Promise提前结束,更新操作可能还没发起就被进程释放,同时你没有捕获更新操作的错误,即便执行报错也不会有任何日志提示。 - 冗余的Promise封装:函数已经标注了
async,Mongoose的所有操作方法原生支持Promise调用,无需手动包裹回调逻辑,反而容易引发异步时序问题。
修正方案
推荐使用async/await写法简化逻辑,避免异步回调嵌套问题:
exports.createBill = async function (b) { // 等待账单创建完成,拿到生成的完整账单文档 const newBill = await Bills.create(b); // 等待关联日历更新完成 await Calendar.findOneAndUpdate( { _id: b.rentalId }, { id_fatturazione: newBill._id } ); // 可按需返回创建的账单数据给外层调用 return newBill; };
如果需要保留原有的回调封装写法,调整如下:
exports.createBill = function (b) { return new Promise((resolve, reject) => { Bills.create(b, function (err, newBill) { if (err) { return reject(err); } Calendar.findOneAndUpdate( { _id: b.rentalId }, { id_fatturazione: newBill._id }, function (err, updateResult) { if (err) { return reject(err); } // 等待更新执行完成后再resolve resolve(updateResult); } ); }); }); };
内容的提问来源于stack exchange,提问作者zupus
相关产品推荐
相关产品推荐

