代码之家  ›  专栏  ›  技术社区  ›  lonix

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

  •  1
  • lonix  · 技术社区  · 7 年前

    我在用电话 passport-http 身份验证库,其文档使用回调-但我使用的是带有async/await的TypeScript类,所以我不确定语法。

    图书馆想要一本书 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 回复  |  直到 7 年前
        1
  •  1
  •   Estus Flask    7 年前

    async 是返回承诺的正则函数的语法糖。如果函数不使用 await ,它不会从中受益 异步的 .

    异步的

    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 回调将导致不正确的行为,即使返回的承诺得到解决。

    但我在一个sync函数中将一个异步回调传递给该构造函数

    PassportBasicStrategy 完成 参数函数是否正确并不重要 异步的 或者不,只要返回的承诺不影响任何事情。

        2
  •  1
  •   Remo H. Jansen    7 年前

    如果您想利用异步/等待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
    })();
    

    promisify 将回调API转换为承诺API,但在这种情况下不可用。