6

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

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

即,如果 3 次调用scheduler彼此紧随其后,则实际上只会执行最后一次调用:

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

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

4

4 回答 4

1

您可以选择使用 Web Worker 线程:

https://developer.mozilla.org/en-US/docs/DOM/Using_web_workers http://www.html5rocks.com/en/tutorials/workers/basics/

于 2012-12-21T21:51:26.187 回答
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");
    }

​
于 2012-12-21T21:59:27.023 回答
1

从理论上讲,您的解决方案看起来可行。没有与您将回调函数传递给您的scheduler函数相关的范围界定问题;回调将关闭它创建的任何环境,就像 JavaScript 中的任何其他函数一样。话虽如此,JavaScript 中的作用域规则可能有点棘手,因此请务必阅读它。

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

话虽如此,您的解决方案中的任何主要问题都可能与您注册的回调有关,而不是与您注册它们的方式有关。

于 2012-12-21T22:02:36.330 回答
1

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

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

创建并返回传递函数的新去抖动版本,该版本将推迟其执行,直到自上次调用以来等待毫秒过去后。对于实现仅在输入停止到达后才应发生的行为很有用。例如:渲染 Markdown 注释的预览,在窗口停止调整大小后重新计算布局等等。

于 2013-02-11T02:23:38.860 回答