繁体   English   中英

打字稿,装饰异步函数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM