【问题标题】:Using async/await with done()/next() middleware functions将 async/await 与 done()/next() 中间件函数一起使用
【发布时间】:2017-10-25 06:03:05
【问题描述】:

我开始使用异步/等待。一般来说,将 await 与中间件 done/next 函数一起使用的模式是什么?

例如,如何将下面代码中的 .then() 替换为 await? localAuthenticate 完成/下一个中间件。我是否需要单独创建一个async 函数才能在其中使用await

我想要这样的东西(没有 try/catch 更好):

function localAuthenticate(User, email, password, hostname, done) {
  try { // where is async?
    // Find user
    let user = await User.findOne({ email: email.toLowerCase() }).exec()
    if(!user) return done(null, false, { message: 'This email is not registered.' });
    // Test password
    user.authenticate(password, function(authError, authenticated) {
      if(authError) return done(authError);
      if(!authenticated) return done(null, false, { message: 'This password is not correct.' });
      return done(null, user);
    });
  } catch(err) { done(err); } 
}

来自 Passport.js 认证中间件的原始代码:

function localAuthenticate(User, email, password, hostname, done) {
  User.findOne({
    email: email.toLowerCase()
  }).exec()
    .then(user => {
      if(!user) {
        return done(null, false, {
          message: 'This email is not registered.'
        });
      }
      user.authenticate(password, function(authError, authenticated) {
        if(authError) {
          return done(authError);
        }
        if(!authenticated) {
          return done(null, false, { message: 'This password is not correct.' });
        } else {
          return done(null, user);
        }
      });
    })
    .catch(err => done(err));
}

【问题讨论】:

    标签: node.js express async-await passport-local


    【解决方案1】:

    await 只能在 async 函数内调用 - 请参阅 the MDN documentation

    • 您的函数必须是async function localAuthenticate(User, email, password, hostname, done)
    • try/catch 是使用 await 时捕获异常的方法,而不是您在直接处理 Promises 时习惯的 .then/.catch

    使用async/await 时,您的函数会近似:

    async function localAuthenticate(User, email, password, hostname, done) {
      try {
        // Find user
        let user = await User.findOne({ email: email.toLowerCase() }).exec()
        if (!user) {
          return done(null, false, { message: 'This email is not registered.' })
        }
    
        user.authenticate(password, function (authError, authenticated) {
          if (authError) {
            return done(authError)
          }
    
          if (!authenticated) {
            return done(null, false, { message: 'This password is not correct.' });
          }
    
          return done(null, user);
        })
      } catch (err) {
        done(err)
      }
    }
    

    进一步阅读:

    【讨论】:

    • localAuthenticate 更改为async 将返回一个承诺。这会影响它作为中间件吗?我从未检查过done() 的返回值
    • 在您调用 next() 之前,中间件不会继续运行 - 您应该在 try 块内执行此操作。
    猜你喜欢
    • 2018-10-17
    • 1970-01-01
    • 2017-11-05
    • 2019-04-15
    • 2014-06-19
    • 2018-01-14
    • 2018-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多