前端小工

好记性不如烂笔头

用setTimeout()方法来模拟setInterval()与setInterval()之间的什么区别?

对于setTimeout()跟setIntervl()之间的区别,你真的了解么?有时候看似简单的东西,往往隐藏一些你不知道的细节。setTimeout(fn,time)是超时调用,它在大于等于time之后调用fn;而setIntervl(fn,time)是间歇调用;每隔time调用一次。下面我要讲的是:用setTimeout()方法来模拟setInterval()与setInterval()之间的什么区别?


使用setInterval()创建的定时器确保了定时器代码规则地插入队列中。这个问题在于:如果定时器代码在代码再次添加到队列之前还没完成执行,结果就会导致定时器代码连续运行好几次。而之间没有间隔。不过幸运的是:javascript引擎足够聪明,能够避免这个问题。当且仅当没有该定时器的如何代码实例时,才会将定时器代码添加到队列中。这确保了定时器代码加入队列中最小的时间间隔为指定时间。

这种重复定时器的规则有两个问题:1.某些间隔会被跳过 2.多个定时器的代码执行时间可能会比预期小。

下面举例子说明:
假设,某个onclick事件处理程序使用啦setInterval()来设置了一个200ms的重复定时器。如果事件处理程序花了300ms多一点的时间完成。
这里写图片描述

这个例子中的第一个定时器是在205ms处添加到队列中,但是要过300ms才能执行。在405ms又添加了一个副本。在一个间隔,605ms处,第一个定时器代码还在执行中,而且队列中已经有了一个定时器实例,结果是605ms的定时器代码不会添加到队列中。结果是在5ms处添加的定时器代码执行结束后,405处的代码立即执行。

为了避免setInterval()的重复定时器的这两个缺点,可以使用下面的这种方法

setTimeout(function(){

    //do something

    setTimeout(arguments.callee,interval);
},interval)

上面实现了递归调用,这样做的好处是:在前一个定时器代码执行完成之前,不会向队列插入新的定时代码,确保不会有任何的缺失间隔。而且,它保证在下一次定时器代码执行之前,至少要等待指定的时间间隔。


参考资料:javascript高级程序设计第三版:重复定时器

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_24024601/article/details/51862488
个人分类: javascript
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭