Javascript的setTimeout函数开始执行太多次

4

我用setTimeout函数创建了一个循环,在执行第二或第三步后,出现了问题,因为它会在同一时间开始执行两次。这是我的函数代码:

var value = 70, 
    intervalID = null;

function interval() {
  intervalID = setTimeout(countDown, 1000);
}

function countDown() {
  value--;
  if(value > 0) {
    clearTimeout(intervalID);
    interval();
  } else {
    endInterval();
  }
}

function endInterval() {
  // do something
}

如果我控制台输出变量值,它会是 69、68,然后在一个函数调用中变量值会减少两次。我没有从任何其他地方调用函数 countDown()。
问题可能出在哪里?
编辑:这段代码现在可以运行了。

3
对我来说运行正常- http://jsfiddle.net/wZ3GM/ 你确定你没有两次调用初始函数吗? - Richard Dalton
你的代码中实际上是一个循环,还是创建了一个“超时循环”? - Prusse
我每次再次调用它时都必须清除超时,然后它开始工作。感谢您的提示。 - JanHocevar
1个回答

5
我建议您通过停止先前的超时来“清理”超时。
function interval() {
  clearTimeout(intervalID);
  intervalID = setTimeout(countDown, 1000);
}

然而,这似乎只是控制症状,而不是治疗病因。因此,最好检测问题的原因。


不需要从自己的回调函数中清除超时。 - Bergi
2
我发现在HTML中有两个具有相同类名的DOM元素,这就是为什么所有东西开始执行两次的原因。 - JanHocevar
@Bergi,你是对的,但是当你将超时ID分配给全局变量时,你永远不知道之前分配给该变量的超时是否已经执行。我认为这违反了完整性,因为我们可以依赖intervalID变量。 - Mikhail Payson
OP的原始解决方案没有使用timeoutID。是的,对于这样的任务,您不应该使用全局变量,而应该使用闭包变量。此外,如果您希望timeoutID被覆盖并且想要清除先前的timeoutID,则需要在覆盖之前执行清除操作。您的方法仅清除“最新”的已分配timeoutID,而忽略了之前的timeoutID。 - Bergi

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