js之重复定时器

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

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

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

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

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

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

173915_5oSw_3544533.png

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

采取链式调用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);

 

 

转载于:https://my.oschina.net/u/3544533/blog/1604801

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值