【问题标题】:Combined delayed function calls in JavascriptJavascript中的组合延迟函数调用
【发布时间】:2012-12-09 11:23:54
【问题描述】:

我不太确定这个的技术术语是什么。我有一个带有交互式图形的 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 的任何警告,尤其是范围问题。这看起来像是我可以在更大范围内使用的可靠模式吗?当settimeout 调用它时,我传递给scheduler 的内联函数是否能够像往常一样在其词法范围内查找所有对象?如果我有几个这样的调度程序实例怎么办?他们能互相干扰吗?有没有其他方法可以做到这一点?

【问题讨论】:

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


【解决方案1】:

【讨论】:

  • 虽然我倾向于同意他的目标受众可能不会。 :p
【解决方案2】:

我会做什么:

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");
    }

​

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-22
        • 1970-01-01
        • 2013-12-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多