首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何避免承诺链中已经发送的标题?

如何避免承诺链中已经发送的标题?
EN

Stack Overflow用户
提问于 2017-10-20 11:34:33
回答 2查看 112关注 0票数 1

我正在进行一项“更改密码”功能。我开始学习更多关于承诺的知识,并有以下代码:

代码语言:javascript
复制
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);
    });
});

我喜欢承诺是如何阻止‘回调地狱’的。问题是,我正在接收一个“已发送的标题”错误。我知道这是因为我无法逃脱链子,它保存了所有的结果(除非你抛出一个错误)。为了解决这个问题,我使用了以下方法:

代码语言:javascript
复制
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');
          });
        });
      });
    });
});

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-20 11:57:50

你可以这样重写它

代码语言:javascript
复制
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函数中返回承诺链。

票数 1
EN

Stack Overflow用户

发布于 2017-10-20 12:13:49

根据您的Node版本的不同,您也可以使用异步/等待来重写它。这通常会使事情更容易推理。

代码语言:javascript
复制
router.post('/change-password', verifyToken, csrfProtection, async (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');
}

try {
    const data = {};
    data.password = req.body.password_new;
    const decoded = await tokenHandler.verifyToken(req.cookies.token);
    const user = await User.findOne({ '_id.user_id': decoded.user });
    data.userId = ObjectId(user._id.user_id);
    const allowed = await bcrypt.compare(req.body.password_current, user.password);
    if (!allowed) {
        return res.redirect('/change-password');
    } else {
        await User.findOneAndUpdate({ '_id.user_id': data.userId }, { password: data.password }, { new: true });
    }
    return res.redirect('/change-password');
} catch (err) {
    return next(err);
}
});

您需要Node.js >= 7来使用异步/等待。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46848259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档