我有以下代码:
async createApiCall(apiCalls: IApiCallsTable):Promise<IApiCallsTable> {
try {
const instance: any = this.db.getEntities().dbo__api_calls.build(apiCalls);
instance.isNewRecord = true;
let result = await this.db.getSequelize().transaction( async (transaction) => {
return instance.save();
});
return Promise.resolve(result.dataValues);
}
catch (error) {
console.log(error);
let message: ILogMessage = {
code: ResponseErrorCode.unknownError,
message: ResponseErrorCode.unknownError.toString(),
meta: error,
sourceFunction : 'ApiCallsQueries: createApiCall()'
};
log.error(message);
return Promise.reject(error);
}
}
我想了解是否有必要对async
标记匿名函数,即this.db.getSequelize().transaction( async (transaction) => { ...
?代码运行完美,但我似乎无法理解标记回调async
的原因,如果内部没有等待它的话?这是推荐的模式和/或最佳实践吗?
PS:关于如何改进此代码的任何进一步建议/建议都非常受欢迎:)
答案 0 :(得分:4)
Sequelize.transaction()
需要一个返回Promise
的回调函数。 async
将任何函数转换为Promise
- 返回函数。
但是,Model.save()
已经返回Promise
,因此您应该只能使用:
await this.db.getSequelize().transaction((tx) => instance.save());
async
指示运行时将函数转换为延续传递样式;也就是说,将其转换为返回Promise
的函数,该函数最终以函数的返回值结算。这与您是否在函数体中使用await
无关。
Sequelize.transaction()
的TypeScript定义将此作为您正在使用的方法的签名:
transaction(autoCallback: (t: Transaction) => PromiseLike<any>): Promise<any>;
在TypeScript中,传递&#34;常规&#34;无效。函数到一个需要返回promise函数的回调参数:
let foo: (() => PromiseLike<string>);
foo = async () => "aaa"; // this compiles
foo = () => Promise.resolve("aaa"); // this does as well
foo = () => "aaa"; // this does *not*
(你可以在TS游乐场here中看到它。)毕竟,Promise<string>
与string
非常不同!
但是,您的代码对已经返回async
的方法使用了Promise<Model>
,这意味着您的回调实际上会返回Promise<Promise<Model>>
。这似乎不对,您的代码实际上应该让TypeScript抱怨result.dataValues
,因为result
的类型为Promise<Model>
,而不是Model
。我猜测是通过从具有以下基本形状的代码开始来实现的:
transaction(async (tx) => {
let foo = await Foo.find();
// use foo
return await foo.save();
});
他们的关键字被恰当地使用,因为它不会通过一个承诺。
答案 1 :(得分:2)
如果您未在函数体内使用await
关键字,则无需将任何函数标记为async
。
此规则的一个例外是,如果您希望该回调的行为类似于Promise
,那么您的代码示例中就不会这样做。
let result = await this.db.getSequelize().transaction( async (transaction) => {
return instance.save();
});
即使instance.save
返回Promise
,我猜它确实如此 - 你已经完全没有使用async
了,因为你已经建立了一个Promise
链。