我正在使用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
修饰符吗?答案 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,但在这种情况下不可用。