【问题标题】:Will setInterval cause browsers to hang?setInterval 会导致浏览器挂起吗?
【发布时间】:2011-07-25 16:26:34
【问题描述】:

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

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

现在,我知道在循环中添加大量代码可能会导致浏览器挂起无论如何,而像 alertpromptconfirm 这样的阻塞代码会停止代码,但有什么好的理由避免setInterval

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

【问题讨论】:

标签: javascript settimeout setinterval


【解决方案1】:

setInterval 不好的原因是因为它会尝试在每个 X MS 执行代码,而不管线程中发生了什么。所以如果你有:

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

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

setTimeout( complexFunction, 1 );

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

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

【讨论】:

  • 这与我听到的信息完全相同。是否有任何源代码或演示代码证明这仍然是一个问题?
  • 这取决于代码的复杂性和您需要考虑的浏览器的速度。您可以随时尝试将任何 V8 基准测试 (v8.googlecode.com/svn/data/benchmarks/v3/run.html) 放入重复 1 毫秒的 setInterval 中,看看它有多糟糕。
  • 这是绝对不正确。如果浏览器在整个时间间隔内都处于忙碌状态,则间隔时间的调用将丢弃,而不是排队。 See example.
  • 我知道这是一个旧线程,但我会注意到我在处理 ajax 请求的间隔时遇到了这个问题。我通过使用超时和嵌套调用来解决它,以便在最后一个解决时重置超时。在台式机上这不是问题,但我在平板电脑上遇到了它(相当糟糕的平板电脑)。
  • 这段代码不会在无限递归的情况下吃掉所有的机器资源,比如栈内存,时间长了吗?
【解决方案2】:

在循环中使用 setTimeout 总是更好,这样您就可以准确地知道何时继续计时:

foo();
function foo(){

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

} 

否则正如你上面所说,浏览器将不得不catch up,并且由于你的循环是无限的,它可能不会。

【讨论】:

  • 这是绝对不正确。如果浏览器在整个时间间隔内都处于忙碌状态,则间隔时间的调用将被丢弃,而不是排队;因此浏览器不会试图“赶上”。 See example.
  • @josh3736 你有没有你的脚本????!十秒后你清除间隔!
  • @josh3736 如果它们被丢弃,您会在旋转数字中看到 1、3、5 等。你没有在你的小提琴中证明任何东西。
  • @FlorianMargaine:不,小提琴会计算调用spin 的次数,不是应该经过多少次间隔。它不应该算奇数。
  • @Neal:出于演示的目的,我们必须以某种方式停止旋转。您可以轻松地制作一个清除间隔的按钮,而不是设置超时来清除它。
猜你喜欢
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 2018-08-22
  • 2012-04-03
  • 1970-01-01
  • 2012-12-20
  • 1970-01-01
相关资源
最近更新 更多