多次延迟调用函数的最快方法

3

如何异步无限次执行函数的最快方法?

我想到了两种方法。

使用间隔

setInterval(function(){
   // do stuff
})

Using while

setTimeout(function(){
   while(true) {
      // do stuff
   }
})

我应该如何处理才能获得尽可能快的结果? 我不关心启动循环所需的时间,只关心执行循环所需的时间。


1
使用requestAnimationFrame - undefined
@elclanrs - 这回答了一个完全不同的问题。 @Afonso - 你的超时+循环除了第一次调用之外并不是异步的。在函数内部放置一个setTimeout( thisFn )调用。 - user578895
你应该实现几种不同的方法,并测量每种方法的时间。 - undefined
严格来说,省略setIntervalsetTimeout的第二个参数是不正确的。 - user663031
3个回答

3
function foo(){
    // do stuff
    setTimeout( foo, 0 );
}

foo();

setInterval有可能在函数执行时间超过间隔时间时,会排队等待执行,这可能会导致数百或数千个函数调用被阻塞。除了第一次调用外,你的while循环不是异步的。


嗯,你的例子在第一次运行时不是异步的。但主要思想已经表达出来了。谢谢 :) - undefined
浏览器似乎不再容易出现堆叠问题,也没有“阻塞队列”:http://jsfiddle.net/gomq31gr/ - undefined

1
第二种方式将是最快的。它只需要一次进入事件队列,然后就会停留在无限循环中。
这将异步运行一个函数,然后在其运行时阻塞UI。如果这不是您想要的,那么这个答案就没有帮助了。但我假设您的两种方法都实现了您想要的功能,您只是想要速度最快的版本。

我是指带有while的那个,我打错了“first”。 - undefined
第二个不是异步的(除了第一次调用)。 - user578895
也许我误解了问题。 - undefined
1
@zyklus 我只是回答关于哪个最快的问题。他是写这段代码的人,我假设它能够达到他的预期。 - undefined

0
当代码编写正确时,setInterval和setTimeout都会采用相同的“最快”方法[1]。
然而,在比较的情况下,循环示例是错误的,并且会导致浏览器冻结(因为循环不再是异步构造)。相反,应该将其改为再次调用setTimout,如下所示:
setTimeout(function fn () {   
   setTimeout(fn, 0);        // loop is implicit with scheduling next timeout
   code();
}, 0);

现在相当于:

setInterval(function () { code() }, 0);

1 虽然在过去可能有所不同,但现在已经不重要了 - 两种方法在调用回调函数和安排下一个事件的速度上都有相同的下限,即在Windows桌面浏览器上至少为4-5毫秒。

由于这是一个固定的下限,通常值得每个回调函数处理多个项目(比如说“做20毫秒的工作”),这样超时/延迟本身就不会占据整体时间的主导地位。还可以运行多个“并行”超时来增加共享回调执行的有效速率;然而,这些事件不能保证分布均匀。

现代浏览器也不受“setTimeout堆叠”影响;因此,为了尽快运行回调函数,任何一种方法都可以。

因此,请使用最能代表问题的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接