【问题标题】:Typescript | Call a function every time a function is called打字稿 |每次调用函数时调用一个函数
【发布时间】:2018-03-05 21:19:04
【问题描述】:

我正在尝试编写 Typescript API 服务。对于服务,我需要一种方法来检查在调用 get 等函数时该方法是否存在。

我意识到我可以做到这样

get(endpoint: string) {
    this.handleRequest();
}

post(endpoint: string, data: any) {
    this.handleRequest();
}

但我并不特别想在每个方法的顶部这样做,所以我不知道是否有办法在 Typescript 类的构造函数中侦听子函数的调用。

能够做到这一点似乎有点牵强,但在像我这样的情况下它会非常有用,所以我不必继续这样做。

export class ApiService {
    base_url: string = 'https://jsonplaceholder.typicode.com/posts';
    methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];

    /**
     * Create an instance of ApiService.
     * @param {string} base_url
     */
    constructor(base_url: string = null) {
        this.base_url = base_url ? base_url : this.base_url;
    }

    get(endpoint: string): string {
        // duplicated line
        this.handleRequest();

        return 'get method';
    }

    post(endpoint: string, data: any): string {
        // duplicated line
        this.handleRequest();

        return 'post method';
    }

    protected handleRequest(): string {
        return 'handle the request';
    }
}

【问题讨论】:

  • handleRequest里面做吗?
  • 哪种方法(或功能)存在或不存在?你想怎么检查?您能否发布完整的代码以及所有重复的检查?
  • 你是什么意思?我希望能够调用api.get('endpoint');,然后它将返回值,但每当api.get('endpoint')api.post('endpoint', ['name' => 'tallent']); 都运行this.handleRequest();'但我不想为所有的重复this.handleRequest();方法。
  • 我已更新问题以包含完整代码
  • 装饰器是一个可行的解决方案吗?您仍然必须将装饰器附加到每个方法。

标签: class typescript ecmascript-6


【解决方案1】:

您可以使用装饰器来执行此操作,该装饰器将使用调用原始实现和您的额外方法的方法覆盖类的所有方法:

function handleRequest() {
    return function<TFunction extends Function>(target: TFunction){
        for(let prop of Object.getOwnPropertyNames(target.prototype)){
            if (prop === 'handleRequest') continue;
            // Save the original function 
            let oldFunc: Function = target.prototype[prop];
            if(oldFunc instanceof Function) {
                target.prototype[prop] = function(){
                    this['handleRequest'](); // call the extra method
                    return oldFunc.apply(this, arguments); // call the original and return any result
                }
            }
        }
    }
}

@handleRequest()
export class ApiService {
    base_url: string = 'https://jsonplaceholder.typicode.com/posts';
    methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];

    /**
     * Create an instance of ApiService.
     * @param {string} base_url
     */
    constructor(base_url: string = null) {
        this.base_url = base_url ? base_url : this.base_url;
    }

    get(endpoint: string): string {
        return 'get method';
    }

    post(endpoint: string, data: any): string {
        return 'post method';
    }

    protected handleRequest(): void {
        console.log('handle the request');
    }
}

let s = new ApiService();
s.get("");
s.post("", null);

【讨论】:

    猜你喜欢
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    相关资源
    最近更新 更多