js之重复定时器

        今天介绍js重复定时器,前段时间在一个项目群里看到有人问,为了解决业务需求须要定义多个定时器来控制事件驱动,我就把本身在一本书上学到的重复定时器一点小知识分享出来,有须要的能够了解了解。javascript

        每一个浏览器窗口、标签页或者frame都有其各自的代码执行队列。这意味着,进行跨frame或者跨窗口的定时调用,当代码同时执行的时候可能会致使竞争条件。不管什么时候须要用到这种通讯类型,最好是在接收frame或者窗口中建立一个定时器来执行代码。java

       使用setTimeout()和setInterval()建立的定时器能够实如今指定的时间间隔执行程序,可是这也只是表面上看去好像代码就在精确指定的时间点上执行了。其实,javascript是运行于单线程的环境中,而定时器仅仅只是计划代码在将来的某个时间执行。执行时机是不能保证的,由于在页面的生命周期里,不一样时间可能有其余代码在控制js进程。实际上,浏览器负责排序,指派某段代码在某个时间点运行的优先级。浏览器

      咱们能够把js想象成在时间线上运行,当页面载入时,首先执行任何包含在<script>元素内的代码,一般是页面生命周期后面要用到的一些简单的函数和变量的声明,有时候也包含一些初始数据的处理等。以后,js进程将等待更多代码执行。当进程空闲的时候,下一个代码会被触发并马上执行。因此,分析得知,js正常工做除了js主线程外,还有一个须要在进程下一次空闲时执行的代码队列。随着页面在其生命周期中的推移,代码会按照执行顺序添加入这个队列,而后在进程空闲时尽快执行队列中的代码片断。在js中没有任何代码是马上执行的,只能保证是尽快执行,一旦进程空闲就马上执行它。函数

      定时器对队列的工做方式是,当特定时间事后去将代码插入。注意:给队列插入添加的这部分代码并不意味着马上执行,而只表示它会尽快执行。指定的时间间隔表示什么时候将定时器的代码添加到队列,而不是什么时候实际执行代码。设定了一个100ms后执行的定时器并不表明到了100ms代码就马上执行,它表示代码会在100ms后被加入到队列,此时,恰好进程处于空闲状态则立刻就执行这段代码,表面上看好像在指定时间内精确执行了。实际上,若是在这个时间点上,进程处于忙状态,此时定时器代码只能等待,等待进程空闲后立刻执行,代码可能明显等待更长时间才能执行。动画

       以setInterval()为例:当业务层出现了设置重复定时器的状况,就会引起两个问题:(1)某些间隔会被跳过,(2)多个定时器的代码执行之间的间隔会比预期小。由于js中有避免的一套机制,仅当未含有定时器的任何代码实例才能添加到队列中,致使某些间隔被跳过;本次还未执行完毕,下一次间隔时间到,就会致使定时器代码同时出现跳过间隔且连续运行好几回状况。线程

        这个例子中第一个定时器在205ms处添加到队列中,可是过了300ms处才执行。当执行这个定时器代码时,在405ms处又给队列添加了一个副本。在下一个时间间隔即605ms处,第一个定时器代码尚未执行完毕,此时进程忙且队列中已经有了一个定时器代码实例(正在执行的定时器代码),根据js的处理机制605ms的这个时间点上的定时器代码不会被插入到队列中,定时器代码跳过。结果在5ms处添加的定时器代码执行结束以后,405ms处添加的定时器代码就马上执行。code

采起链式调用setTimeout()避免使用setInterval()的重复定时器的2个缺点.排序

(function(){

//处理中

setTimeout(arguments.callee,inerval);

},interval);

 

       这个模式链式调用了setTimeout(),每次执行的时候就建立一个新的定时器。第二个setTimeout()调用arguments.acllee来获取对当前执行的函数的引用,并为其设置另外一个定时器。这样作的好处是,在前一个定时器代码执行完以前,不会向队列出插入新的定时器代码,确保不会有任何缺失的间隔。并且,还能够保证在下一次定时器代码执行以前,至少要等指定的间隔,避免了连续的运行。生命周期

实现将一个div元素向右移动的动画,当坐标在200像素时中止。队列

setTimeout(function(){

var div=document.getElementById("mydiv");

left=parseInt(div.style.left)+5;

div.style.left=left+"px";

if(left<200)

{

setTimeout(arguments.callee,50);

}

},50);
相关文章
相关标签/搜索