在等待的函数中使用用于回调的异步关键字有什么目的?



我有以下代码:

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链。

最新更新