在Javascript中组合延迟函数调用

时间:2012-12-21 21:45:19

标签: javascript jquery node.js javascript-events settimeout

我不太清楚这个术语的含义是什么。我有一个带有交互式图形的GUI。用户与GUI交互后,我需要执行一些CPU密集型操作。但是,用户输入非常频繁,所以我只想在例如之后调用该函数。没有用户输入1000毫秒。在我使用的模式下面:

scheduler = (function(){
    var timer;
    function exec(call, delay){
        clearTimeout(timer);
        timer = setTimeout(call, delay);
    };
    return exec;
})()

即。如果对scheduler的3次调用是在彼此之后完成的,那么实际上只会执行最后一次:

scheduler(function(){alert('foo')}, 1000);
scheduler(function(){alert('bar')}, 1000);
scheduler(function(){alert('zoo')}, 1000);

它似乎有效,但感觉有点hacky我有点担心Javascript setTimeout的任何警告,特别是范围问题。这看起来像我可以在更大范围内使用的可靠模式吗?当scheduler调用它时,我传递给settimeout的内联函数是否能像往常一样查找其词法范围内的所有对象?如果我有几个这样的调度程序实例呢?他们会互相干扰吗?有没有其他方法来实现这个目标?

4 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

我会做什么:

http://jsfiddle.net/gunderson/4XXQ4/1/

    var severQueue = [];
    var delay;

    $("#inputSquare").mousemove(onMouseMove);

    function onMouseMove(){
        if (delay){
           clearTimeout(delay);
        }
        serverQueue.push("doSomething")
        delay = setTimeout(sendToServer, 1000);
    }

    function sendToServer(){
        console.log(serverQueue.length);
        delay = null;
        $("#inputSquare").addClass("activated");
        // do some ajax using serverQueue
        // we'll just simulate it with another timeout
        for (var i in serverQueue){
            serverQueue.pop();
        }
        onComplete = setTimeout(onAjaxComplete, 1000);
    }

    function onAjaxComplete(){
        $("#inputSquare").removeClass("activated");
    }

​

答案 2 :(得分:1)

理论上,您的解决方案看起来会起作用。没有与您将回调函数传递给scheduler函数相关的范围问题;回调将关闭它所创建的任何环境,就像JavaScript中的任何其他函数一样。话虽如此,scoping rules can be a bit tricky in JavaScript,所以请务必阅读。

在实践中,可能存在与setTimeout相关的某些特定于浏览器的问题,这些问题可能导致此解决方案无法使用。例如,某些浏览器执行setTimeout回调的频率可能会有所不同,因此您将等待的时间超过预期的回执执行时间。所有setTimeout回调都将按顺序执行;它们永远不会被并行执行。但是,您可以保证将执行的顺序。

所有这一切,你的解决方案中的任何主要问题可能更多地与你注册的回调有关,而不是你注册它们的方式。

答案 3 :(得分:1)

underscore.js中的debounce function正是这样做的:

  

去抖动 _.debounce(function, wait, [immediate])

     

创建并返回传递函数的新debounced版本,该版本将推迟执行,直到等待毫秒之后   自上次调用以来经过的时间。对实施有用   只有在输入停止到达后才会发生的行为。   例如:渲染Markdown注释的预览,重新计算   窗口停止调整大小后的布局,依此类推。