定时器对队列的工作方式:当特定时间过去后将代码插人。注意,给队列添加代码并不意味着对它立刻执行,而只能表示它会尽快执行。设定一个150ms后执行的定时器不代表到了150ms代码就立刻执行,它表示代码会在150ms后被加入到队列中。如果在这个时间点上,队列中没有其他东西,那么这段代码就会被执行,表面上看上去好像代码就在精确指定的时间点上执行了。其他情况下,代码可能明显地等待更长时间才执行。


重复定时器:

这种重复定时器的规则有两个问题: (1)、 某些间隔会被跳过; (2) 、多个定时器的代码执行之间的间隔可能会比预期的小。假设,某个onclick事件处理程序使用setInterval()设置了一个200ms间隔的重复定时器。如果事件处理程序花了300ms多-点的时间完成,同时定时器代码也花了差不多的时间,就会同时出现跳过间隔且连续运行定时器代码的情况。

在这里插入图片描述

这个例子中的第1个定时器是在205ms处添加到队列中的,但是直到过了300ms处才能够执行。当执行这个定时器代码时,在405ms处又给队列添加了另外一个副本。在下一个间隔,即605ms处,第一个定时器代码仍在运行,同时在队列中已经有了一个定时器代码的实例。结果是,在这个时间点上的定时器代码不会被添加到队列中。结果在5ms处添加的定时器代码结束之后,405ms处添加的定时器代码就立刻执行。

解决方法: 使用链式调用。

1
2
3
4
setTimeout(function () {
//处理程序
setTimeout(arguments.callee, interval);
}, interval);

这个模式链式调用了setTimeout(),每次函数执行的时候都会创建一个 新的定时器。第二个setrimeout ()调用使用了arguments.callee来获取对当前执行的函数的引用,并为其设置另外一个定时器。这样做的好处是,在前一个定时 器代码执行完之前, 不会向队列插 人新的定时器代码,确保不会有任何缺失的间隔。而且,它可以保证在下一次定时器代码执行之前,至少要等待指定的间隔,避免了连续的运行。这个模式主要用于重复定时器。

举个栗子:
每隔一段时间,div就会向右移动,当左坐标为200时就停止移动。

1
2
3
4
5
6
7
8
9
setTimeout(function() {
var div = document.getElementById("div");
left = parseInt(div.style.left) + 5;
div.style.left = left + "px";

if (left < 200) {
setTimeout(arguments.callee, 50);
}
}, 50);



愿你的坚持终有收获。