【问题标题】:Call a function inside async function at a js class在 js 类的异步函数中调用函数
【发布时间】:2019-07-17 10:05:55
【问题描述】:

您好,我是 javascript 编程新手。

我有一个 node express 项目,我正在尝试在我的 AuthenticationController 类中创建一个登录方法。

我现在的登录方式是这样的:

const User = require('../models/User')

class AuthenticationController {

  async login(req, res) {
    const { email, password } = req.body
    console.log('step 1')
    var hashPassword = await userPassword(email)
    console.log(hashPassword)
    console.log('step 2')
    return res.status(200).json({ 'msg': 'Log in OK!' })

  }

  userPassword(email) {
    User.findOne({ email: email }).exec(function(err, user) {
      if (err) return err
      else return user.password
    })
  }
}

但是我收到一个错误,说 userPassword 未定义,我不知道为什么。所以我的疑问是:为什么会发生这种情况,以及如何正确地做到这一点?

我也检查了这个问题,但他们没有帮助我:

我的控制台上的错误消息:

(node:28968) UnhandledPromiseRejectionWarning: ReferenceError: userPassword is not defined ...

(node:28968) UnhandledPromiseRejectionWarning:未处理的承诺拒绝。此错误源于在没有 catch 块的情况下抛出异步函数内部,或拒绝未使用 .catch() 处理的承诺。 (拒绝编号:1)

(node:28968) [DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。将来,未处理的 Promise 拒绝将使用非零退出代码终止 Node.js 进程。

【问题讨论】:

  • await this.userPassword(email) 因为userPasswordprototype

标签: javascript node.js express mongoose async-await


【解决方案1】:

login 不是指userPassword 方法,而是指不存在的同名函数。

Promise 应该是链式的,但事实并非如此。 userPassword 预计会返回一个承诺,但它使用过时的 Mongoose 回调 API。

显示UnhandledPromiseRejectionWarning 意味着错误在login 中未正确处理,而它们应该正确处理。正如this answer 中所述,Express 不支持承诺,因此错误应由开发人员处理。

应该是:

  async login(req, res) {
      try {
        const { email, password } = req.body
        var hashPassword = await this.userPassword(email)
        return res.status(200).json({ 'msg': 'Log in OK!' })
      } catch (err) {
        // handle error
      }
  }

  async userPassword(email) {
    const { password } = await User.findOne({ email: email });
    return password;
  }

【讨论】:

  • 感谢您的解释,我明白了。我尝试了您的解决方案,但现在出现此错误:TypeError: Cannot read property 'userPassword' of undefined 我不明白为什么 userPassword 未定义
  • 这取决于您如何使用问题中未显示的login。我很肯定你将它作为回调传递,而它没有绑定到正确的上下文。见stackoverflow.com/questions/20279484/…。在这种情况下,您根本不需要类,它是一种反模式。 Vanilla Express 无法从 OOP 中受益。您可以制作 loginuserPassword 常规函数,这就是通常的做法。
  • 我将我的类更改为只有模块导出中的方法,成功了!您是否有任何链接,以便我可以在 JS 中阅读有关此反模式的更多信息?谢谢
  • @LucasAndrade 这不是具有特定名称的反模式,只是我见过很多次的糟糕的 Express 配方。 Express 是功能性的,它不能有效地将类表示的实体用于它自己的 API(中间件、路由),除非你利用一些围绕它的框架(例如 NestJS)。为了 OOP 而使用 OOP 是一种不好的做法(这是奥卡姆剃刀的问题)。无状态或仅静态类的使用也是如此(它们被视为美化的命名空间,这就是模块的用途)。对于其他框架和语言,情况可能会有所不同。
  • 这是一个很好的答案,但要回答为什么 userPassword 未定义的问题,您在类中调用了一个不存在的 FUNCTION。添加 this 后,您现在指的是您的类的方法。
【解决方案2】:

这个错误来了,因为你没有处理 promise 的错误。始终在 try/catch 块中使用 async/await。

try{
  async login(req, res) {
    const { email, password } = req.body
    console.log('step 1')
    var hashPassword = await userPassword(email)
    console.log(hashPassword)
    console.log('step 2')
    return res.status(200).json({ 'msg': 'Log in OK!' })
  }
}catch(e){
    console.log(e)
}

【讨论】:

    猜你喜欢
    • 2021-12-25
    • 2019-01-20
    • 2012-07-25
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    相关资源
    最近更新 更多