当在Promise函数中使用Update方法时,Mongoose有时会跳过向DB添加数据的操作

时间:2018-12-25 13:12:45

标签: node.js express mongoose

我正在使用Node.js Express框架编写API,该框架向其他一些外部API发出请求。我需要在数据库中有每个请求的日志(我通过mongoose使用MongoDB)。

问题是,当我尝试通过猫鼬Update方法将日志推送到子文档数组时,有时它保存在数据库中,有时却保存在数据库中,在两种情况下都没有任何错误。 这是执行代码的一些部分:

// externalApiCtrl模块

const request = require('request');
const mongoose = require('mongoose');
const httpContext = require('express-http-context');
const PolicyLog = mongoose.model('PolicyLog');

const updatePolicyLog = (id, log) => {
  return new Promise((resolve, reject) => {
    PolicyLog.update({ "policyId": mongoose.Types.ObjectId(id) },
      { $push: { logs: log } }
    ).then(() => {
      resolve();
    }).catch(err => {
      reject(err);
    });
  });
};

exports.createPolicy = (policy) => {
  return new Promise((resolve, reject) => {
    // prepare request body and do some other stuff here

    let options = {}; // request options (url, method, headers & body)
    request(options, (error, response, body) => {
      if (error)
        reject(error);

      let policyLocalId = httpContext.get("policyLocalId");
      // here comes the trouble
      updatePolicyLog(policyLocalId, {
        method: "reqName",
        request: "reqBody",
        response: body
      }).then(() => {
        resolve();
      }).catch(err => {
        return reject(err)
      });
    });

  });
};

//主控制器模块

exports.create = (req, res) => {
  let externalApiCtrl = require('./controllers/external-api.controller.js');
  externalApiCtrl.createPolicy(req.policy)
    .then(result => {
      return res.json(result);
    }).catch(err => {
    return res.status(501).json(err);
  });
};

因此,当调用updatePolicyLog函数时,有时有时会在解析猫鼬更新方法(PolicyLog.update())之前解决该问题。 有什么办法解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

最后我找到了解决方案。 问题不在于猫鼬,而在于 express-http-context 模块。有时,在对API的多个并行请求期间,上下文会丢失并且policyLocalId变量的值未定义,因此mongoose不会更新日志。 发生在Node 硼lts (v.6.16.0)上,将其更新为 carbon lts (v8.15.0)可以解决此问题。