使用TypeScript和Node / Passport将异步回调传递给类构造函数

时间:2019-02-08 13:32:31

标签: node.js typescript asynchronous async-await passport.js

我正在使用passport-http身份验证库,该文档的文档使用回调-但是我正在将TypeScript类与async / await一起使用,因此我不确定语法。

库需要verify回调,该回调查询数据库-这是一个异步操作。我将其定义为单独的异步函数(因此更易于测试):

public verify = async (username: string, password: string, done: (error: any, user?: any) => void): Promise<void> => {
  // read from database asynchronously...
  try {
    const user = await this.UserRepository.findByUsername(username);
    if (!user)
      return done(null, false);
    if (user.Password !== password)
      return done(null, false);
    return done(null, user);
  }
  catch (e) {
    return done(e);
  }
}

然后我将其提供给图书馆:

//public async init(): Promise<void> {                       // also works
public init(): void {
  const strategy = new PassportBasicStrategy(this.verify);   // async callback!
  passport.use(strategy);
}

我的问题:

  • 如果我将其声明为init()而不是async init(),它将起作用。我认为这是因为仅当函数具有async时才需要await修饰符吗?
  • 但是我在同步函数中向该构造函数传递了一个异步回调!...正确吗?

2 个答案:

答案 0 :(得分:1)

async是返回promise的常规函数​​的语法糖。如果某个函数不使用await,则不能从async中受益。

如果接受回调的API不使用返回的诺言,则可能存在问题。只要解决了此问题,使用promise并因此使用async是可以接受的。由于API无法处理拒绝,因此应由用户处理:

verify = async (username: string, password: string, done: (error: any, user?: any) => void): Promise<void> => {
  try {
    // reads from the database asynchronously...
    done(null, user);
  } catch (err) {
    done(err);
  }
}

即使已解决返回的诺言,也不会调用done回调会导致错误的行为。

  

但是我在同步函数中向该构造函数传递了一个异步回调

PassportBasicStrategy可能接受异步回调,这就是为什么回调具有done参数的原因。函数是否为async无关紧要,只要返回的promise不影响任何事情即可。

答案 1 :(得分:1)

如果您想利用async / await API。在这种情况下,由于API基于回调,因此您可以执行以下操作:

const veryfy: BasicVerifyFunction = (username, password, done) => {
    (async () => {
        try {
            const user = await User.findOne({
                username: username,
                password: password
            });
            done(null, user ? user : false);
        } catch(err) {
            done(err);
        }
    })();
};

passport.use(new BasicStrategy(veryfy));

请注意异步IIFE

(async () => {
    // Use await here
})();

Node.js还包括一个名为promisify的帮助程序函数,用于将回调API转换为Promise API,但在这种情况下不可用。