简体   繁体   English

Javascript 中的组合延迟函数调用

[英]Combined delayed function calls in Javascript

I am not quite sure what the technical term for this is.我不太确定这是什么技术术语。 I have a GUI with interactive graphics.我有一个带有交互式图形的 GUI。 After the user has interacted with the GUI, I need to perform some CPU intensive action.在用户与 GUI 交互后,我需要执行一些 CPU 密集型操作。 However, user input is very frequent, so I only want to call the function after eg 1000ms of no userinput.但是,用户输入非常频繁,所以我只想在例如 1000 毫秒没有用户输入后调用该函数。 Below the pattern that I use:在我使用的模式下方:

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

Ie if the 3 calls to scheduler are done right after each other, only the final one will actually be executed:即,如果对scheduler的 3 次调用紧随其后完成,则实际上只会执行最后一个:

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

It seems to work, but it feels a bit hacky I am a little worried about any caveats of Javascript setTimeout , especially the scoping problems.它似乎工作,但感觉有点hacky 我有点担心Javascript setTimeout任何警告,尤其是范围问题。 Does this seem like a reliable pattern I could use on a larger scale?这似乎是我可以在更大范围内使用的可靠模式吗? Will the inline function that I pass to scheduler be able to lookup all objects in its lexical scope as usual, when it is called by settimeout ?settimeout调用时,我传递给scheduler的内联函数是否能够像往常一样在其词法范围内查找所有对象? What about if I have several of these scheduler instances?如果我有几个这样的调度程序实例呢? Could they interfere with each other?他们会互相干扰吗? Is there an alternative way of accomplishing this?有没有其他方法可以实现这一点?

What I would do:我会怎么做:

http://jsfiddle.net/gunderson/4XXQ4/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");
    }

​

In theory, your solution looks like it will work.理论上,您的解决方案看起来可行。 There are no scoping problems related to you passing a callback function to your scheduler function;没有与您将回调函数传递给scheduler函数相关的范围界定问题; the callback will close over whatever environment it was created in, just like any other function in JavaScript.回调将在它创建的任何环境中关闭,就像 JavaScript 中的任何其他函数一样。 That being said, scoping rules can be a bit tricky in JavaScript , so make sure that you read up on it.话虽如此,JavaScript 中的作用域规则可能有点棘手,因此请务必仔细阅读。

In practice, there may be some browser-specific issues related to setTimeout that may make this solution unworkable.在实践中,可能存在一些与setTimeout相关的特定于浏览器的问题,这可能会使此解决方案不可行。 For example, the frequency at which certain browsers execute setTimeout callbacks may vary such that you'll be waiting longer than you expect for a callback to be executed.例如,某些浏览器执行setTimeout回调的频率可能会有所不同,因此您等待回调的时间将比预期的要长。 All setTimeout callbacks will be executed sequentially;所有的setTimeout回调都会依次执行; they'll never be executed in parallel.它们永远不会并行执行。 However, you have guarantees as to what order they will be executed in.但是,您可以保证它们将按什么顺序执行。

All that being said, any major gotcha in your solution will likely have more to do with the callbacks that your registering rather than the way in which you're registering them.尽管如此,您的解决方案中的任何主要问题都可能与您注册的回调有关,而不是与您注册它们的方式有关。

The debounce function in underscore.js does exactly this: underscore.js 中的debounce函数正是这样做的:

debounce _.debounce(function, wait, [immediate])反跳_.debounce(function, wait, [immediate])

Creates and returns a new debounced version of the passed function that will postpone its execution until after wait milliseconds have elapsed since the last time it was invoked.创建并返回传递函数的新去抖动版本,该版本将推迟执行,直到自上次调用以来经过等待毫秒。 Useful for implementing behavior that should only happen after the input has stopped arriving.用于实现只有在输入停止到达后才会发生的行为。 For example: rendering a preview of a Markdown comment, recalculating a layout after the window has stopped being resized, and so on.例如:渲染 Markdown 评论的预览,在窗口停止调整大小后重新计算布局,等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM