Javascript代理:检测递归

时间:2017-11-07 10:29:50

标签: javascript

我想创建一个简单的性能记录器:

function makePerformanceMeasured(target) {
    return new Proxy(target, {
        apply: (target, thisArg, args) => {
            if(!target.name) {
                throw 'The function must have a name'
            }
            console.time(target.name);
            const result = target.apply(thisArg, args); 
            console.timeEnd(target.name);
            return result;
        }
    })
}

对于非递归函数 - 一切运作良好:

function isPrime(n) {
    if(n < 2) {
        return false;
    }
    for(var i = 0; i < n; i++) {
        if(n % i === 0) {
            return false;
        }
    }

    return true;
} 
isPrime = makePerformanceMeasured(isPrime); 
isPrime(100); // 0.001ms false

但是使用递归函数:

function fact(n) {
    if(n < 2) {
        return 1;
    }
    return n * fact(n - 1);
}
fact = makePerformanceMeasured(fact);
fact(4);
// 0.025ms 
// 0ms
// 0ms
// 24

我想在Proxy apply陷阱中检测 - 如果函数是递归调用的 - 只对堆栈中的第一个函数调用进行时间测量。 谢谢!

1 个答案:

答案 0 :(得分:3)

您可以设置一个标记,以便记住您是否已经在通话中:

function makePerformanceMeasured(target) {
    var isCalled = false;
    return new Proxy(target, {
        apply: (target, thisArg, args) => {
            if (!isCalled) {
                 console.time(target.name);
                 isCalled = true;
                 const result = Reflect.apply(target, thisArg, args);
                 isCalled = false;
                 console.timeEnd(target.name);
                 return result;
            } else {
                 return Reflect.apply(target, thisArg, args);
            }
        }
    })
}