我正在使用“更改密码”功能。我开始学习有关Promises的更多信息,并具有以下代码:

router.post('/change-password', verifyToken, csrfProtection, (req, res, next) => {
  if (!req.body.password_current || !req.body.password_new) {
    req.flash('info', 'Please fill in both fields.');
    return res.redirect('/change-password');
  }
  const data = {};
  data.password = req.body.password_new;
  tokenHandler.verifyToken(req.cookies.token)
    .then((decoded) => {
      return User.findOne({ '_id.user_id': decoded.user });
    })
    .then((user) => {
      data.userId = ObjectId(user._id.user_id);
      return bcrypt.compare(req.body.password_current, user.password);
    })
    .then((allowed) => {
      if (!allowed) {
        return res.redirect('/change-password');
      }
      console.log('I am not here');
      return User.findOneAndUpdate({ '_id.user_id': data.userId }, { password: data.password }, { new: true });
    })
    .then(() => {
      return res.redirect('/change-password');
    })
    .catch((err) => {
      return next(err);
    });
});


我喜欢Promises如何防止“回调地狱”。问题是我收到“已发送标题”错误。我知道那是因为我无法逃脱这个链条,并且它保存了所有结果(除非您抛出错误)。为了解决这个问题,我使用了以下方法:

router.post('/change-password', verifyToken, csrfProtection, (req, res, next) => {
  if (!req.body.password_current || !req.body.password_new) {
    req.flash('info', 'Please fill in both fields.');
    return res.redirect('/change-password');
  }
  const data = {};
  data.password = req.body.password_new;
  tokenHandler.verifyToken(req.cookies.token)
    .then((decoded) => {
      User.findOne({ '_id.user_id': decoded.user }).then((user) => {
        data.userId = ObjectId(user._id.user_id);
        bcrypt.compare(req.body.password_current, user.password).then((allowed) => {
          if (!allowed) {
            return res.redirect('/change-password');
          }
          User.findOneAndUpdate({ '_id.user_id': data.userId }, { password: data.password }).then((doc) => {
            console.log(doc);
            return res.redirect('/change-password');
          });
        });
      });
    });
});


问题是:是否有更好的解决方案来解决“已发送标头”错误。因为我觉得我的解决方案实际上距离“回调地狱”结构只有几步之遥。

最佳答案

您可以这样重写它

router.post('/change-password', verifyToken, csrfProtection, (req, res, next) => {
  if (!req.body.password_current || !req.body.password_new) {
    req.flash('info', 'Please fill in both fields.');
    return res.redirect('/change-password');
  }
  const data = {};
  data.password = req.body.password_new;
  tokenHandler.verifyToken(req.cookies.token)
    .then((decoded) => {
      return User.findOne({ '_id.user_id': decoded.user });
    })
    .then((user) => {
      data.userId = ObjectId(user._id.user_id);
      return bcrypt.compare(req.body.password_current, user.password);
    })
    .then((allowed) => {
      if (!allowed) {
        return res.redirect('/change-password');
      }
     else{
        console.log('I am not here');
        return User.findOneAndUpdate({ '_id.user_id': data.userId }, { password: data.password }, { new: true })
          .then(() => {
                return res.redirect('/change-password');
             });
       }
    })
    .catch((err) => {
      return next(err);
    });
});


您可以从then函数中返回承诺链。

07-26 05:40