You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 15:21:00