javascript - node.js 使用 mongoose 链接多个异步函数

标签 javascript node.js express mongoose

我有一个看起来像这样的函数,至少现在它可以工作。

exports.changePassword = (req, res) => {
  const { token, password, confirmPassword } = req.body

  User.findOne({resetPasswordToken: token}, (err, user)=>{
    if(!user){
      return res.status(400).send({
        msg: 'Invalid token or token has been used!'
      })
    }

    const hash_password = bcrypt.hashSync(password, 10)
    User.findOneAndUpdate({_id: user._id}, 
      {hash_password}, 
      (err, result)=>{

        if(err){
          return res.status(400).send({
            msg: err
          })
        }

        User.findOneAndUpdate({_id: user._id},
          {resetPasswordToken: ''},
          (err, result)=>{
            if(err){
              return res.status(400).send({
                msg: err
              })
            }

            res.status(200).json({
              status: 1,
              data: 'Your password has been changed.'
            })
          }
        )
      })
  })
}

我只是觉得写这段代码很糟糕,因为我认为它有几个问题:

  1. 回调 hell
  2. 错误处理代码重复

对于第一个问题,也许我可以使用完成参数?并做一些链接?有时我怀疑我是否需要处理每一个错误回调。您将如何重写上面的函数以使其变得更加优雅?

最佳答案

您可以将 Promise 与 Mongoose 结合使用,这将有助于解决回调 hell 问题:

exports.changePassword = (req, res) => {
  const { token, password, confirmPassword } = req.body

  User.findOne({resetPasswordToken: token}).then((user)=>{
    // do stuff with user here 

    const hash_password = bcrypt.hashSync(password, 10)
    // Now chain the next promise by returning it
    return User.findOneAndUpdate({_id: user._id}, {hash_password});
  }).then((result)=>{
    // Now you have the result from the next promise, carry on...
    res.status(200).json({
      status: 1,
      data: 'Your password has been changed.'
    })
  }).catch(err => {
    // Handle any errors caught along the way
  });
}

由于这些都是 promise ,因此您实际上可以使用 ES6 async/await 语法使其变得更加简洁:

// Note this now has the async keyword to make it an async function
exports.changePassword = async (req, res) => {
  const { token, password, confirmPassword } = req.body

  try {
    // Here is the await keyword
    const user = await User.findOne({resetPasswordToken: token});

    // do stuff with user here 

    const hash_password = bcrypt.hashSync(password, 10)

    // Now the next promise can also be awaited
    const result = await User.findOneAndUpdate({_id: user._id}, {hash_password});

    // Finally send the status
    res.status(200).json({
      status: 1,
      data: 'Your password has been changed.'
    });
  } catch (err) {
    // Any promise rejections along the way will be caught here
  });
}

关于javascript - node.js 使用 mongoose 链接多个异步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48128300/

相关文章:

javascript - 使用 Javascript 导入文本文件

javascript - d3.js 上的条形放大

node.js - 如何将交易系统构建成.then()链?

node.js - 如何将用户数据传递到所有 View 中?

node.js - NodeJS - app.use(function(err, req, res, next){}) 和 process.on ('uncaughtException' , function(err){}) 之间的区别

node.js - React 服务器未启动 - 与 renderProps 有关

c# - 动态更改 ASP.NET C# 中的项目而不需要回发?

javascript - Spring MVC 应用程序中 RequireJS 库加载缓慢

node.js - 如何仅在使用特定路由时在 Koa 中指定静态文件夹?

javascript - 使用多个路由时,使用express和chokidar进行热重载会导致http header 发送错误