难以理解的工作装饰功能

时间:2015-01-21 14:47:50

标签: javascript

是一个功能:

var f = function(a) { console.log(a) };

function throttle(func, ms) {
    var stop = false, savedThis, savedArgs;

    return function wrapper() {
        if(stop) {
            savedArgs = arguments;
            savedThis = this;
            return;
        } 

        func.apply(this, arguments)
        stop = true;

        setTimeout(function() {
            stop = false;
            if(savedArgs) {
                wrapper.apply(savedThis, savedArgs);
                savedArgs = savedThis = null;
            }
        }, ms);
    };
}

// brake function to once every 1000 ms
var f1000 = throttle(f, 1000);

f1000(1); // print 1
f1000(2); // (brakes, less than 1000ms)
f1000(3); // (brakes, less than 1000ms)

第一个呼叫f1000 (1)显示1. f1000 (2),第二个呼叫不起作用,但它将保留在savedAggs链接到第二个呼叫的参数。第三次启动也不起作用,但它会覆盖第三次调用参数的链接。通过1000毫秒setTimeout导致匿名函数,变量stop将在false的含义内。工作条件和递归调用wrapper。但后来我无法理解发生了什么?此代码有效时:savedArgs = savedThis = null;

1 个答案:

答案 0 :(得分:2)

这个功能有点难以理解,是的。它的工作是将调用速率限制为每1000毫秒最多一次 - 但是如果它们发生得更频繁,它也会在超时结束后重复上一次调用。

最好写一下

function throttle(func, ms) {
    var stop = false, savedThis, savedArgs;
    function invoke() {
        stop = true; // the last invocation will have been less than `ms` ago
        func.apply(savedThis, savedArgs);
        savedThis = savedArgs = null;
        setTimeout(function() {
            stop = false; // the timeout is over, start accepting new invocations
            if (savedArgs) // there has been at least one invocation during
                           // the current timeout
                invoke();  // let's repeat that
        }, ms);
    }
    return function wrapper() {
        savedArgs = arguments;
        savedThis = this;

        if (stop)
            return;
        else
            invoke();
    };
}