js 反复调用settimeout 需要手动clearTimeout 吗?

var timeOut=null;
function polling() {

timeOut = setTimeout(function () {
  init();
  timeOut && clearTimeout(timeOut);
  polling();
}, 5e3);

}
polling();

阅读 31.7k
5 个回答

看情况。
由于JS的单线程机制,计时器语句会被加入到执行队列。比如setInterval方法,如果该队列中有未执行的setInterval,那么再往里加的时候就会被自动忽略,同一个计时器调用等待执行的队列中最多只有一个执行。这里感谢@manxisuo 的提醒:但如果存在多个setInterval情况就复杂了,比如有N个setInterval那么等待队列中也有最多N个执行语句,需要看情况而定是否需要清除。
setTimeout既然只调用一次,如果有需要清除那么可以手动取消。
计时器原理可以看看John Resig大神的这篇博客:How JavaScript Timers Work
网上有人给翻译了:javascript中的定时器(How JavaScript Timers Work)

  • setTimeout:触发一次后,就停止了,无需手动clear。当然你可以在它触发前clear它,这样它一次都不会触发了。

所以,需要还是不需要,不是绝对的,要看你的使用场景。如果你在某种情况下,在计时器触发前需要终止它,那就需要,否则就不需要。

不需要,因为它只会执行一次,在反复调用时,除了手动clearTimeout外,只需要把条件去了就可以停止。

setTimout & clearTimeout

可以认为成延时执行,调用后产生一个id,你可以保存到一个变量里。
你可以使用clearTimeout(id),来移除这个延时执行。可以认为这是一个闹钟。

setInterval & clearInterval。

同理。但是,此方法是每隔你设置的时间会执行一次,可以在你想要的情况下结束掉这个计时器。

所以依据你的代码

  1. 不应该在setTimeout的回调里面写clearTimeout,因为这个时候已经没有用了,除非使用setInterval

  2. 如1所说,如果你要每隔5秒运行一次init,那就用setInterval吧。

依你的使用场景而定
如果你的定时调用可能需要在开始调用前取消掉,那么就需要clearTimeout了

var timeOut=null;
function polling() {
    timeOut = setTimeout(function () {
      init();
      //timeOut && clearTimeout(timeOut);//执行到此处时定时器已经被触发,你调用clearTimeout是没有任何效果的
      polling();
    }, 500);
}
polling();

//点击后停止定时器执行
$('#button').click(function(){
    timeOut && clearTimeout(timeOut);//此时会将处于待处理状态的定时器函数取消执行
});
推荐问题
宣传栏