setInterval 会导致浏览器挂起吗?

IT技术 javascript settimeout setinterval
2021-03-08 20:25:55

几年前,我被警告不要setInterval长时间使用,因为如果被调用的函数运行时间超过指定的时间间隔,它可能会导致浏览器挂起,然后无法赶上:

setInterval( function(){
  foo = 'bar_' + i++;
}, 1 );

现在,我知道,在一个循环中添加大量的代码可能会导致浏览器挂起无论如何,这阻止这样的代码alertprompt以及confirm将停止它的轨道的代码,但是有没有什么好的理由,以避免setInterval

注意:我知道如何进行递归setTimeout调用(因为这是我一直在使用的),这个问题是我试图弄清楚是否仍然值得使用它们,或者是否setInterval可以安全使用。

2个回答

原因setInterval很糟糕,因为无论线程中发生了什么,它都会尝试在每个 X MS 执行代码。所以如果你有:

setInterval( complexFunction, 1 ); // complexFunction takes >1 MS to complete

...您可能最终setInterval会在自己的代码完成之前尝试重新执行几次!但是,您可以setTimeout类似地使用并避免此问题:

setTimeout( complexFunction, 1 );

function complexFunction() {
  // complex code
  setTimeout( complexFunction, 1 );
}

...nowcomplexFunction只会在它自己的代码完成后再次调用它自己,所以如果它自己的代码完成时间超过 1 毫秒,你将不会像处理任何积压一样处理setInterval

这取决于代码的复杂性和您需要考虑的浏览器的速度。您始终可以尝试将任何 V8 基准测试 ( v8.googlecode.com/svn/data/benchmarks/v3/run.html ) 放入 setInterval 并重复 1 毫秒,看看它有多么糟糕。
2021-04-16 20:25:55
我知道这是一个旧线程,但我会注意到我在与 ajax 请求的间隔中遇到了这个问题。我通过使用超时和嵌套调用来解决它,以便在最后一个解决时重置超时。在台式机上这不是问题,但我在平板电脑上遇到了它(非常糟糕的平板电脑)。
2021-04-18 20:25:55
这是绝对不正确的如果浏览器在整个时间间隔期间都处于忙碌状态两次,则该时间间隔调用将被丢弃,而不是排队。 参见示例。
2021-04-19 20:25:55
这段代码不会在无限递归的情况下吃掉所有机器资源,比如堆栈内存,经过很长时间吗?
2021-05-03 20:25:55
这和我听到的信息完全一样。是否有任何源代码或演示代码来证明这仍然是一个问题?
2021-05-06 20:25:55

在循环中使用 setTimeout 总是更好,这样你就知道什么时候继续计时:

foo();
function foo(){

   setTimeout (function(){
      foo = 'bar_' + i++;
      foo();
     }, 1 );

} 

否则正如你上面所说的,浏览器将不得不这样做catch up,因为你的循环是无限的,它可能不会。

这是绝对不正确的如果浏览器在整个时间间隔期间都很忙,间隔到期两次,则间隔调用将被丢弃,而不是排队;因此浏览器不会试图“赶上”。 参见示例。
2021-04-22 20:25:55
@josh3736 你有没有看过你的剧本????!十秒后清除间隔!
2021-04-26 20:25:55
@FlorianMargaine:不,小提琴计算spin调用了多少次而不是应该经过多少个间隔。不应该算奇数。
2021-04-26 20:25:55
@Neal:为了演示的目的,我们必须以某种方式停止旋转。您可以轻松地制作一个清除间隔的按钮,而不是设置超时来清除它。
2021-05-14 20:25:55
@josh3736 如果它们被丢弃,您会在旋转数字中看到 1、3、5 等。你没有在你的小提琴中证明任何东西。
2021-05-15 20:25:55