为什么我的异步代码在控制器中有效,但在模型中无效?

时间:2019-05-02 16:45:16

标签: node.js express async-await sequelize.js

我正在使用bcrypt 3.0.6。我的Model文件中包含以下代码:

User.prototype.validPassword = async function(password) {
  try{
    // original code:
    // return await bcrypt.compare(password, this.password);
    const match = await bcrypt.compare(password, this.password);
    console.log(match);
  } catch(error) {
    console.log(error);
    return false;
  }
};

然后我从控制器中调用它:

try {
  if (!req.body.userName || !req.body.password) throw "Invalid Login"
  user = await User.findOne({
    where: { userName: req.body.userName }
  })
  if (!user) throw "Invalid login"
  const match = user.validPassword(req.body.password);
  // const match = await bcrypt.compare(req.body.password, user.password);
  if (!match) throw "Invalid login";
  // build token
  ...
});
} catch(error) {
  res.status(500).json({
    "msg": "Server Error",
    "error": error,
  })
}

调试时,matchundefined

如果我在控制器中进行比较,它将按预期工作。我宁愿比较在模型文件中。我在这里做什么错了?

我是异步/等待代码的新手,但是我已经成功地使用它在同一项目中实现了其他几种控制器方法。

2 个答案:

答案 0 :(得分:1)

花了我一段时间,但我终于能够弄清楚我做错了什么。我太多使用了异步/等待。以下代码按我的预期工作:

User.prototype.validPassword = function(password) {
  return bcrypt.compare(password, this.password);
};

我错过了bcrypt.compare返回承诺的事实(或更直接地,事实的重要性)。我只需要退还该承诺并await即可解决。

在控制器中:

  if (!user) throw "Invalid login";
  const match = await user.validPassword(req.body.password);
  if (!match) throw "Invalid login";
  // build token ...

答案 1 :(得分:0)

据我在js中使用async/await并理解它,您应该在validPassword方法中返回一个promise。因为该方法本身使用的是await,所以它是一个异步方法,它在控制器的常规流程之外运行。

因此,根据您的代码,我建议将其更改为与此类似的内容:

User.prototype.validPassword = function(password) {
  return new Promise(async function (resolve, reject) {
    try{
      // original code:
      // return await bcrypt.compare(password, this.password);
      const match = await bcrypt.compare(password, this.password);
      console.log(match);
      resolve(match)
    } catch(error) {
      console.log(error);
      reject();
    }
  }
};

和控制器:

try {
  if (!req.body.userName || !req.body.password) throw "Invalid Login"
  user = await User.findOne({
    where: { userName: req.body.userName }
  })
  if (!user) throw "Invalid login"
  try {
    const match = await user.validPassword(req.body.password);
    If (!match) throw "invalid login";
    // build token
  } catch (err) {
    throw "Server error";
  }

  ...
});
} catch(error) {
  res.status(500).json({
    "msg": "Server Error",
    "error": error,
  })
}

作为替代方案,您可以拒绝诺言,如果match为false并在捕获中评估拒绝项