简体   繁体   English

你能用setInterval来异步调用函数吗?

[英]Can you use setInterval to call functions asynchronously?

The following code is taken from Project Silk (a Microsoft sample application) The publish method below loops thru an an array of event callBacks and executes each one. 以下代码取自Project Silk(Microsoft示例应用程序)。下面的发布方法循环通过一个事件callBack数组并执行每个。 Instead of using a for loop setInterval is used instead. 而不是使用for循环而是使用setInterval。

The documentation says this allows each subscriber callback to be invoked before the previous callback finishes. 文档说这允许在前一个回调完成之前调用每个订阅者回调。 Is this correct? 它是否正确? I thought the browser would not allow the execution of the function inside the interval to run until all prior executions of it had finished. 我认为浏览器不允许在间隔内执行该函数,直到它的所有先前执行完成为止。

Is this really any different than doing a for loop? 这和for循环有什么不同吗?

that.publish = function (eventName, data) 
{
    var context, intervalId, idx = 0;
    if (queue[eventName]) 
    {
        intervalId = setInterval(function () 
        {
            if (queue[eventName][idx]) 
            {
                context = queue[eventName][idx].context || this;
                queue[eventName][idx].callback.call(context, data);
                idx += 1;
            } 
            else { clearInterval(intervalId); }
        }, 0);
    }

setInterval(..., 0) can be used to yield control to the browser UI, to prevent it from freezing if your code takes a long time to run. setInterval(..., 0)可用于控制浏览器UI,以防止代码需要很长时间才能运行。

In this case, that.publish will exit almost immediately before any callback has been executed. 在这种情况下, that.publish将在任何回调执行之前几乎立即退出。 Each callback will then run "in the background" - they will be placed in the event loop, and each one will yield to the browser to do it's thing before the next callback is executed. 然后每个回调将“在后台”运行 - 它们将被放置在事件循环中,并且每个回调将在下一次回调执行之前屈服于浏览器来执行它。

This seems like a good idea in event processing, because you don't want event processing to freeze the browser even if there are a lot of them or some take a long time to finish. 这似乎是事件处理中的一个好主意,因为您不希望事件处理冻结浏览器,即使它们有很多或者有些需要很长时间才能完成。

About the documentation - as stated, it is incorrect. 关于文档 - 如上所述,它是不正确的。 Javascript is single-threaded. Javascript是单线程的。 But if you were to call publish() a few times in a row, it is true that those calls would all finish before any callbacks are executed, because of the setTimeout . 但是如果你连续几次调用publish() ,那么在执行任何回调之前,这些调用都会因为setTimeout Maybe this is what the documentation means? 也许这就是文档的意思?

Using setInterval here does make the execution sort of "asynchronous", because it schedules the execution of the callback for the next time the main execution thread is available. 在这里使用setInterval会使执行排序为“异步”,因为它会在下次主执行线程可用时安排回调的执行。

This means that the callback executions should not block the browser because any other synchronous processing will take place before the callbacks (because the callbacks are scheduled to run only when the main execution thread has a spare millisecond) - and that's what makes this construct "better" than a regular for loop - the fact that the callbacks won't block the browser and cause the dreaded "This page has a script that's taking too long" error. 这意味着回调执行不应该阻止浏览器,因为任何其他同步处理将在回调之前发生(因为回调被安排为仅在主执行线程具有备用毫秒时运行) - 这就是使这个构造“更好”的原因“比常规for循环 - 回调不会阻止浏览器并导致可怕的事实”这个页面有一个太长的脚本“错误。

The side effect of this scheduling pattern is that the timeout is only a "suggestion" - which is why they use 0 here. 这种调度模式的副作用是超时只是一个“建议” - 这就是他们在这里使用0的原因。

See: http://ejohn.org/blog/how-javascript-timers-work/ 请参阅: http//ejohn.org/blog/how-javascript-timers-work/

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

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