[英]Typescript, decorate async function
我正在尝试用一些异步函数#2 装饰异步函数#1。
例如
function func2(param) {
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
//make async operations and then return descriptor
}
@func2(param)
async function func1() {
await .... //some async operation
await .... //some async operation
}
所以,主要思想是在装饰器中执行一些异步操作,然后在主函数中执行其他异步调用。
是否可以使用打字稿装饰器来实现这一点?
先感谢您。
装饰器只能用于类方法而不能用于常规函数,因此这是一个限制,但如果将函数放在类中,则可以轻松替换原始函数并执行其他异步任务:
function func2(param: number) {
return (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<(... params: any[])=> Promise<any>>) => {
let oldFunc = descriptor.value;
descriptor.value = async function (){
var result = await oldFunc.apply(this, arguments);
await delay(param) //some async operation
console.log("delay 3");
return result;
}
}
}
class Test {
@func2(1000)
async func1(timout: number) {
await delay(timout) //some async operation
console.log("delay 1");
await delay(timout) //some async operation
console.log("delay 2");
}
}
new Test().func1(1000);
// Util function
async function delay(timeout: number) {
return new Promise<void>((resolve) => setTimeout(() => {
resolve();
}, timeout));
}
如果有人偶然发现我遇到的相同问题,并希望使用异步函数装饰器(在我的情况下是从 DB 访问令牌对象)检索一些值并将其传递给一个方法,您可以使用这些方法。
您只需要推送到参数数组。
装饰器功能
export const authorizeXero = () => {
return (target: any, propertyKey: string, descriptor: any) => {
const fn = descriptor.value;
descriptor.value = async function (...args: any[]) { // anything that was passed in the arguments in instance method (it can be empty)
let tokens = await fetchSavedXeroTokens()
tokens = await checkIfXeroTokensStillValid({...tokens})
tokens = await refreshXeroTokens({...tokens})
tokens = await saveXeroRefreshToken({...tokens})
const {access_token,refresh_token} = tokens
args.push(access_token) // pushes value to the array that will be available to decorated methods
return fn.apply(this, args);
}
}
}
实例方法的例子
@authorizeXero()
async getLatestInvoices (...params:any) {
const accessToken = params[0] // everything that is stored in args under decorator function
const allInvoices = await this.fetchInvoices({accessToken,maxPages:30})
const xe = allInvoices.map((invoice:any)=>{
return {'invName':invoice.InvoiceNumber,'orderName':invoice.Reference}
})
return xe
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.