js进阶之重复的定时器
使用setInterval()创建的定时器确保了定时器代码规则的插入队列中,这个的问题是:定时器代码可能在代码再次被添加到队列之前还没有完成执行,结果导致定时器代码连续运行了好几次,而之间没有任何停顿。(js引擎可以避免这个问题,当使用setInterval()时,仅当没有该定时器的任何其他代码实例时,这确保了定时器代码加入到队列中的最小时间间隔为指定间隔这就会出现两个问题)
1.某些间隔会被跳过
2.多个定时器的代码执行之间的间隔可能会比预期的小。
比如某个onclick事件处理程序,使用setInterval()设置一个200ms间隔的重复定时器。如果事件处理程序花了300ms,同时定时器代码也花了300多ms,就会出出现跳过间隔且连续运行定时器代码的情况。
这个 例子中第一个定时器是在205ms处添加到队列中的,但是过了300ms处才能够执行,当执行这个定时器代码时候,在405ms处又给队列添加了另一个副本,在下一个间隔,即605ms处,第一个定时器代码仍在运行,同时在队列中已经有了一个定时器代码的实例,结果是,在这个时间点上的定时器代码不会被添加到队列中,就是说,在5ms处添加的定时器代码结束后,405ms处添加的定时器代码就立刻执行。205ms的那个直接跳过了。
为了避免这两个问题可以用如下代码
setTimeout(function() {
//处理中
setTimeout(arguments.callee, interval);
},interval)
setTimeout 每次函数执行时候都会创建一个新的定时器,第二个setTimeout调用使用了arguments.callee 来获取对当前执行函数的引用,并为其设置另外一个定时器,这么做的好处:在前一个定时器代码执行完之前,不会向队列插入新的定时器代码,确保了不会有缺失的间隔,而且确保了下一次定时器代码执行之前,至少等待指定的间隔。
写个简单的例子:
执行一段代码,将一个div代码向右移动,当移到坐标200时候停止。
setTimeout(function(){
let div = document.getElementById(“myDiv”)
left = parseInt(div.style.left) + 5;
div.style.left = left + “px”;
if(left < 200) {
setTimeout(argument.callee,50)
}
},50)