setInterval 和setTimeout 重新赋值clear的问题(上)
我习惯把问题用标题写出来,简洁明了,
js新手入门3月不到,问题自然一大堆,碰到这个问题是因为自己尝试做一个小插件,问题我简化一下:
1 var timer; 2 3 function t1(){ 4 timer = setInterval(function(){ 5 console.log("abc"); 6 },1000) 7 } 8 9 t1(); //执行一次 10 //t1(); //再执行一次 11 12 $(document).click(function(){ 13 clearTimeout(timer); 14 })
第二次执行被注释上了,此时body的click事件能clear掉timer,但是如果去掉第二次执行的注释,你认为click还能clear掉timer吗??
注,我的timer已经是全局变量了,所以这里不关timer全局,local的事情。
因为我自己的插件中setInterval的时间间隔非常短,加上t1触发不明显,我不知道触发了几次,所以当时clear不掉的原因找了半天。但这段代码一看调试台就清楚,当执行两次t1的时候,每秒log两次abc-----事实上我们开启了两个定时器。
更明显的是,你可以在最后添加一行 console.log(timer), 并且分别在执行一次和执行两次的情况下观察,你会发现执行一次console.log(timer)的值为1,而两次console的值为2。我开始以为timer的值代表开启的定时器个数,但事实上用timer的ID形容这个数字更为准确,id为1的timer,id为2的timer。
现在再去解释为什么不能clear掉的原因似乎容易明白了,t1()执行第一次,给我们的timer赋值,指向一个内部ID为1的定时器,第二次t1执行,timer重新赋值了,timer指向了ID为2的定时器。此时你去clearTimeout,clear的只是id为2的那个定时器了,而第一个定时器我们已经失去对它的引用了,无法关闭了,同样的情况也可以发生在setTimeout上。
(注:定时器的ID是在什么范围是唯一的,作为学材料的工科妹子,我不太清楚这个线程的原理,这两天心力交瘁,也没有去测试过)。
关于解决的办法,晚一点我会查一下牛人,貌似也没有很好的方法。我之前用过一个array来保存timer,通过push方法,和pop方法,可以保证每个定时器引用,和clear。功能是达到了,但是非常不漂亮+恶心。
欢迎留言~
浙公网安备 33010602011771号