节点JS [错误:发送后不能设置标头。]

时间:2016-10-20 01:48:13

标签: node.js mongoose promise

嗨,我可以说我有这样的代码:

router.get('/blablabla', function(req, res, next) {
    model
      .findOne({condition : req.body.condition})
      .then(function(data) {
        if(data) {
          return res.send("data already exists");
        }
        else {
          //DO CREATE THE NEW DATA

          return modelInstance.save();
        }
      })
      .then(function(data) {
        if(data) res.send("new data successfully saved");
      })
      .catch(function(err) {
        console.log(err);
      });
  });

在当前条件下,如果数据已存在,则会出现错误

**[Error: Can't set headers after they are sent.]
Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)**

为什么会出现此错误?根据我的知识调用res.send()之后,它下面的所有后面的代码都不能正确执行?

我返回data.save()因为我想避免嵌套语句。

更新替代解决方案

router.get('/blablabla', function(req, res, next) {
    model
      .findOne({condition : req.body.condition})
      .then(function(data) {
        if(data) {
          return new Promise(function(resolve, reject) {
            return resolve();
          });
        }
        else {
           //DO CREATE THE NEW DATA

          return modelInstance.save();
        }
      })
      .then(function(data) {
        if(data) res.send("new data successfully saved");
        else res.send("data already exists");
      })
      .catch(function(err) {
        console.log(err);
      });
  });

1 个答案:

答案 0 :(得分:1)

你的第二个.then()处理程序仍然会执行,因为承诺没有分支,它被链接,因此链继续运行,因此你将进行两次res.send()操作,并且'是什么导致你看到的错误。

当你这样做时:

return res.send("data already exists");

您只是从.then()处理程序返回一个值。由于该值不是被拒绝的承诺,因此承诺将保持解决状态,并且链中的下一个.then()处理程序将执行。

你可以这样做:

router.get('/blablabla', function (req, res, next) {
    model.findOne({condition: req.body.condition}).then(function (data) {
        if (data) {
            return res.send("data already exists");
        } else {
            //DO mMODIFY THE DATA AND THEN SAVE THE DATA
            return data.save().then(function () {
                res.send("new data successfully saved");
            });
        }
    }).catch(function (err) {
        console.log(err);
    });
});

或者,您可以这样做(修改您的第二次尝试 - 假设data.save()返回一个解析为值的承诺):

router.get('/blablabla', function(req, res, next) {
    model
      .findOne({condition : req.body.condition})
      .then(function(data) {
        if (!data) {
          //DO mMODIFY THE DATA AND THEN SAVE THE DATA
          return data.save();
        }
        return data;
      })
      .then(function(data) {
        if(data) res.send("new data successfully saved");
        else res.send("data already exists");
      })
      .catch(function(err) {
        console.log(err);
      });
  });