Node.js UnhandledPromiseRejectionWarning:错误:发送标头后无法设置标头

时间:2018-11-20 04:48:08

标签: node.js

我是node.js的新手,并且想通过两次查询mongodb来在单个响应中发送UserMatch的数据。

 router.get('/preview/',  checkAuth, (req, res)=> {
    const errors = {};
    const match = {}
    User.findOne({_id: req.user.id})
    .then(user => {
      if (!user) {
        return res.status(404).json({errors: 'Could not find a user' });
      }

      Match.findOne({ user: req.user.id }).then(m => { 
        console.log('match found!');
        match = m;
      }).catch(err=> res.status(404).json(err));  // <-error occures here

      res.status(200).json({user, match});
    })
    .catch(err=> res.status(404).json(err));

  });

但是我得到这个错误:

(node:8056) UnhandledPromiseRejectionWarning: Error: Can't set headers after they are sent.

我该如何解决?

1 个答案:

答案 0 :(得分:2)

请查看代码中添加的注释。

router.get('/preview/',  checkAuth, (req, res)=> {
    const errors = {};
    const match = {}
    User.findOne({_id: req.user.id})
    .then(user => {
      if (!user) {
        return res.status(404).json({errors: 'Could not find a user' });
      }

      Match.findOne({ user: req.user.id }).then(m => { 
        console.log('match found!');
        match = m;
      }).catch(err=> res.status(404).json(err));  // <-error occures here because you sent the response if error occurs

      res.status(200).json({user, match}); // this will be executed even if there is an error so it will again try to send the response
    })
    .catch(err=> res.status(404).json(err));

  });

改进的代码:

router.get('/preview/', checkAuth, (req, res) => {
  const errors = {};
  User.findOne({ _id: req.user.id })
    .then((user) => {
      if (!user) {
        return res.status(404).json({ errors: 'Could not find a user' });
      }
      Match.findOne({ user: req.user.id })
        .then((m) => {
          console.log('match found!');
          res.status(200).json({ user, m }); // send the success response when the match found
        })
        .catch((err) => res.status(404).json(err)); // send the error response when erro thrown
    })
    .catch((err) => res.status(404).json(err));
});