我有以下代码:
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:关于如何改进此代码的任何进一步建议/建议都非常受欢迎:)
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 中,将"常规"函数传递给需要 promise 返回函数的回调参数是无效的:
let foo: (() => PromiseLike<string>);
foo = async () => "aaa"; // this compiles
foo = () => Promise.resolve("aaa"); // this does as well
foo = () => "aaa"; // this does *not*
(你可以在这里的 TS 操场上看到它。毕竟,Promise<string>
与string
有很大的不同!
但是,您的代码在已经返回Promise<Model>
的方法上使用async
,这意味着您的回调实际上返回了一个Promise<Promise<Model>>
。这似乎不对,你的代码实际上应该导致TypeScript抱怨result.dataValues
,因为result
将是Promise<Model>
类型,而不是Model
。我猜它是从具有以下基本形状的代码开始实现的:
transaction(async (tx) => {
let foo = await Foo.find();
// use foo
return await foo.save();
});
他们的关键字被适当地使用,因为它不仅仅是通过承诺。
如果不在函数体内使用await
关键字,则无需将任何函数标记为async
。
此规则的一个例外是,如果您希望该回调的行为类似于Promise
,而您在代码示例中没有这样做。
let result = await this.db.getSequelize().transaction( async (transaction) => {
return instance.save();
});
即使instance.save
返回一个Promise
,我猜它确实如此 - 你已经在这里涵盖了根本没有使用async
,因为你已经在构建一个适当的Promise
链。