是否可以创建一个节流功能,可以将另一个功能(也有参数)和时间延迟作为参数

Sta*_*inn 3 javascript closures throttling

因此,我已经编写了一个函数(基于下划线限制),用于不接受参数的函数,但我想使其足够通用,以传递具有可变数量参数的函数.这就是我所拥有的:

    (function () {

    var lastTime = new Date().getTime();

    function foo() {
        var newTime = new Date().getTime();
        var gap = newTime - lastTime; // Travels up scope chain to use parents lastTime.  Function has access to variables declared in the same scope
        console.log('foo called,  gap:' + gap);
        lastTime = newTime; // Updates lastTime
        //console.log(x);
        //x++;
    }

    var throttle = function(func, wait) {
        var result;
        var timeout = null; // flag updated through closure
        var previous = 0; // time last run updated through closure

        return function() { //func, wait, timeout, previous available through scope
            var now = new Date().getTime();
            var remaining = wait - (now - previous);

            if (remaining <= 0) {
                clearTimeout(timeout);
                timeout = null;
                previous = now;
                result = func.apply(this, arguments); //func is available through closure
            }
            return result;
        };
    };

    document.addEventListener("scroll", throttle(foo, 1000));
    //document.addEventListener("scroll", throttle(foo(5), 2000));

}());
Run Code Online (Sandbox Code Playgroud)

但我想将foo修改为foo(x)并使其工作

    (function () {

    var lastTime = new Date().getTime();

    function foo(x) {
        var newTime = new Date().getTime();
        var gap = newTime - lastTime; // Travels up scope chain to use parents lastTime.  Function has access to variables declared in the same scope
        console.log('foo called,  gap:' + gap);
        lastTime = newTime; // Updates lastTime
        console.log(x);
        x++;
    }

    var throttle = function(func, wait) {
        var result;
        var timeout = null; // flag updated through closure
        var previous = 0; // time last run updated through closure

        return function() { //func, wait, timeout, previous available through scope
            var now = new Date().getTime();
            var remaining = wait - (now - previous);

            if (remaining <= 0) {
                clearTimeout(timeout);
                timeout = null;
                previous = now;
                result = func.apply(this, arguments); //func is available through closure
            }
            return result;
        };
    };

    document.addEventListener("scroll", throttle(foo(5), 2000));

}());
Run Code Online (Sandbox Code Playgroud)

Gab*_*s00 10

throttle(foo(5), 2000)

无法工作,因为当您使用括号调用函数时,您正在调用该函数.

foo它传递给油门时,您需要包装一个匿名函数.

throttle(function(){
    foo(5)
}, 2000)
Run Code Online (Sandbox Code Playgroud)

如果你想跟踪原始值x.在函数中包装foo并返回foo.捕获闭包范围中的值.

function foo(x) {
  return function(){
    var newTime = new Date().getTime();
    var gap = newTime - lastTime; // Travels up scope chain to use parents lastTime.  Function has access to variables declared in the same scope
    console.log('foo called,  gap:' + gap);
    lastTime = newTime; // Updates lastTime
    console.log(x);
    x++;
  }        
}
Run Code Online (Sandbox Code Playgroud)

那么你实际上可以我们,throttle(foo(5), 2000)因为它不会在第一次调用时执行预期的功能.

示例:http://repl.it/XOj/5(已修复示例)

一个接受任意数量的args的解决方案,修改油门:

function throttle(func, wait, args){
    //do throttle stuff 
    func.apply(null, args);
}
Run Code Online (Sandbox Code Playgroud)

然后throttle(foo(5), 2000)成为throttle(foo, 2000, [5])