JS定时器学习总结
1,两种定时器的差别以及互相之间的等价实现
(1):在JS中有两种定时器:setInterval和setTimeout
分别的作用是定时循环执行和延时执行。
(2):两种定时器的差别:
使用setTimeval定时器进行定时循环操作时,它并不是严格定时执行的,它所作的事情,只是每间隔一定时间执行一次对应的函数,而下一次再次进行此函数的计时在前一次函数开始执行时就已经开始执行,即如果用setInterval定时器进行函数的循环操作它真实的间隔时间其实是设定间隔时间减去函数运行时(除去第一,第一次函数开始执行前的停顿时间还是设定时间)。举个栗子,我用setInterval设定了间隔时间为2000毫秒,而函数运行时间需要1000毫秒,第一次停顿时间为2000毫秒,而之后的停顿时间都变为2000-1000毫秒。
这种情况发生的原因是什么呢?
js是运行在单线程的环境中的,所以这就意味着定时器就成了要执行的计划,而不是必须要执行的。这是什么意思的呢,通俗的讲,就是定时器按时发配任务,我执不执行就不一定了,比如我定时2秒,而函数运行时间要3秒,在前一个函数还没有运行完时,下一个函数虽然定时器按时发配任务了,但是我并不运行。
如何解决这个问题呢?
思路1:使用setTimeout定时器,在函数结束时继续加入setTimeout定时器,有点类似于函数中的递归调用。
思路2:依旧使用setInterval定时器,但是在进入函数时直接停止该定时器,这里利用了setInterval第一次定时标准的特性,实现了一个类似于setTimeout定时器的功能,然后在函数结束时重启该定时器,思路大体上与上述思路类似。
(3)两种定时之间的等价实现:
思路与上述解决问题的思路类似:
利用setTimeout实现setInterval:setTimeout定时器的函数内部在函数结束时调用此定时器(递归)。就可以实现类似setInterval的功能。
利用setInterval实现setTimeout的功能:利用setInterval第一次的停顿,在进入函数时直接停止计时器,就可以实现setTimeout。
2,定时器中的参数。
A:定时器的语法是setInterval(code,millisec,lang) 这里以setInterval为例子。
一共三个参数(可以有好多个,全靠lang撑)
(1):code :这个参数是必需的,它代表计时器中要调用的函数或者要执行的代码串。
(2):这个参数也是必须的,它代表计时器的周期执行或调用code之间的时间间隔,以毫秒计。简而言之,这就是计时器中的时间间隔。
(3):lang:这个参数不是必须的 ,它有什么用呢?这个参数的作用我会在在下面如何说明(卖个关子)。
B:如何给计时器的回调函数传参?
举个栗子:
一个函数 function one(str){
alert(“str”);
}
var timer1=setInterval(one(str),1000);
这样写会它会直接执行函数,并不会有停顿时间。
如何解决这个问题?即如何正确地给定时器中的回调函数传参数呢?
有三种方法:
(1):
通过加引号方式。即变成setInterval(“one(str)”,1000)
这种方法是最简单的但也是功能最不全的,这种方法的使用条件是str必须是windows对象,否则会报错。
(2):
利用闭包
举个栗子:
function one(str){
alert(str);
}
function _one(str){
return function(){
one(str);
}
}
setInterval(__one(str),3000);
这种方法基本没有什么问题。
(3):利用定时器的第三个参数,即lang。
第三个参数lang有什么不一样的功能呢?
第三个参数开始,包括第三个参数都将会当做定时器的回调函数的参数依次传入回调函数。
什么意思呢,就是你可以吧传入的参数放在第三个第四个第n个参数,然后它会自动传入。
举个栗子:
//setTimeout
setTimeout(function(l,m,n){
console.log(l,m,n);
},100 ,1,10,100);
//setTimeout 分别传入了第三四五个参数,在回调函数中也同时接收了三个参数,最终输出为
//1 10 100
回调函数所接收的参数只是第一次传入的值需要注意的是,如果外部参数的值
类型,不论第三四五参数如何变化,回调函数所接受的参数只是第一次传入的值。
利用这个参数还可以实现一些功能,
var doc=document.getElementById('div');
setTimeout(function(){
doc.style.color='red';
},10000,setTimeout(function(){
doc.style.color='black';},
5000));
上面的结果是,div元素内的字体样式5秒后变黑。因为第三个参数也是一个定时器,5秒后就会开启。
3,定时器时间间隔的最小允许参数
定时器的时间间隔是有最小值的。
HTML5标准规定
setTimeout的最短时间间隔是4毫秒;
**setInterval的最短间隔时间是10毫秒。**也就是说,小于10毫秒的时间间隔会被调整到10毫秒。
由上可知,就算我们把间隔时间设置为0甚至设置为负值,定时器也不会立刻执行。
后台模式
大多数电脑显示器的刷新频率是60HZ,大概相当于每秒钟重绘60次。因此,最平滑的动画效的最佳循环间隔是1000ms/60,约等于16.6ms。
为了节电,对于那些不处于当前窗口的页面,浏览器会将时间间隔扩大到1000毫秒。
另外,如果笔记本电脑处于电池供电状态,Chrome和IE9以上的版本,会将时间间隔切换到系统定时器,大约是16.6毫秒。
4,定时器返回的数值
定时器会返回一个数字值id,可以由clearInterval(id)或clearTimeout(id)来实现对对应定时器的清除。
每一个定时器返回的值都是不同的。
setInterval()/setTimeout()BOM中的Window对象方法,以返回数字值id来清除定时器的排序位置存在一定的兼容性问题。通常采用一个变量接受定时器产生的返回值id,通过变量来这种方式来实现关闭定时器操作的兼容性。
5,定时器时间间隔的准确性
定时器的时间间隔完全准确吗?
答案是否定的,它会有每一次的时间间隔都会有几率有1毫秒的上下浮动差。(在IE浏览器下误差更大)