浅析javascript三种定时器原理和异同
Posted 十九万里
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅析javascript三种定时器原理和异同相关的知识,希望对你有一定的参考价值。
念念不忘 必有回想
前言
众所周知js定时器有两种 setTimeout和setInterval 还有一个新增的requeTanimationFrame(动画API)也被加入到了面试经常考察的范围,那么我就从是什么 怎么用,什么时候用,他们的区别是什么来简述一下这三者的关系
1、setTimeout(延时器)
setTimeout完整的写法其实是window.setTimeout 是window的一个属性,由于window是全局作用域,通常我们写的时候就省略了
setTimeout()方法用来指定某个函数或字符串在指定的毫秒数之后执行。它返回一个整数,表示定时器的编号,这个值可以传递给clearTimeout()用于取消这个函数的执行
setTimeout有两个参数,第一个是function:表示将要执行的函数或者代码,这里可以
第二个参数delay是推迟执行的毫秒数。如果省略就是马上执行
在ie9以下 只允许setTimeout执行两个参数
ie9以上可以多个参数
还有一个不常用的第三个参数:
在MDN中是这样解释的
清除setTimeout方法:
setTimeout()对应的是 clearTimeout(id);
2、setInterval (定时器)
同样 setInterval也是window上的方法,window被省略
setInterval() 方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间延迟。
每次调用都有固定的时间间隔,会返回一个时间间隔ID 该ID唯一地标识时间间隔,在清除定时器的时候就调用此ID来清除。
同样的 setInterval和setTimeout的参数相同都是三个
function code
delay
arg1, …, argN 可选
这里我就不重复了
清除定时器的方法:
setInterval()对应的是 clearInterval(id);
一个小问题:setInterval有什么缺点呢:
1.不去关心回调函数是否还在运行
在某些情况下,函数可能需要比间隔时间更长的时间去完成执行。比如说是用setInterval每隔5秒对远端服务器进行轮询,网络延迟,服务器无响应以及其他因素将会阻止请求按时按成。结果会导致返回一串无必要的排成队列请求。
2.忽视错误
因为某些原因,setInterval调用的代码中会出现一个错误,但是代码并不会中止执行而是继续执行错误的代码。
3.缺乏灵活性
除了前面提到的缺点之外,我非常希望setInterval方法能有一个表明执行次数的参数而不是无休止的执行下去。
3、requeTanimationFrame(动画API)
这个点我也是在复习面试的时候发现的
先来看MDN怎么解释这个API的
window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行>
会返回一个callback参数
下一次重绘之前更新动画帧所调用的函数(即上面所说的回调函数)。该回调函数会被传入DOMHighResTimeStamp参数,该参数与performance.now()的返回值相同,它表示requestAnimationFrame() 开始去执行回调函数的时刻。
也就是说 requeTanimationFrame不需要设置时间间隔,大多数电脑显示器的刷新频率是60hz,大概相当于每秒钟重绘60次,大多数浏览器都会对重绘操作加以限制,不炒股欧显示器的重绘频率,一次超过显示屏频率用户体验也不会提升,所以最佳循环事件是1000ms/60,约等于16.6ms
特点:
requestAnimationFrame会把每一帧中所有的DOM操集中起来,在一次重绘或者回流中完成,并且重绘或回流的时间间隔会紧紧跟随浏览器的刷新频率
在隐藏或者不可见的元素中,requestAnimationFrame将不会进行重绘,这就意味着更少的cpu GPU和内存的使用量
requestAnimationFrame是由浏览器专门为提供的api 在运行的时候浏览器会自动优化方法的调用,并且如果页面不是激活状态的话,动画会自动暂停,有效节省了CPU的开销。
官网文档地址
4、这三个方法什么时候应用
setTimeout用于延迟执行某方法或功能
setInterval则一般用于刷新表单,对于一些表单的假实时指定时间刷新同步
5、setInterval和setTimeout的区别
1、setTimeout在规定的时间后使用一次就停止操作了
setInterval会按照这个规定的时间一直循环下去
2、两种定时器清除方法不一样
setInterval()对应的是 clearInterval(id);
setTimeout()对应的是 clearTimeout(id);
6、使用setTimeout实现setInterval
原理:
在setTimeout内部调用function的时候再次调用setTimeout方法 实现循环定时达到setInterval的效果
代码实现:
简单版本:
setTimeout(function(){
//do something
setTimeout(arguments.callee,interval);
},interval)
复杂版本:
function interval(func, w, t){
var interv = function(){
if(typeof t === “undefined” || t-- > 0){
setTimeout(interv, w);
try{
func.call(null);
}
catch(e){
t = 0;
throw e.toString();
}
}
};
setTimeout(interv, w);
};
这个interval函数有一个叫做inter的内部函数,它通过setTimeout来自动被调用,在inter中有一个闭包,它检查了重复次数,调用了回调函数并通过setTimeout再次调用了interv。万一回调函数中出现了一个异常,interv调用将会终止,异常也会被抛出。
当然不能保证函数在固定的间隔中执行,但是它保证新的区间开始时上一个区间中的函数已经执行完毕,我认为这是非常重要的。
那么问题也来了,使用setTimeout实现setInterval和 setInterval有什么区别呢
setTimeout(fn, time),超时调用,在时间大于等于 time 时调用;
setInterval(fn, time),是间歇调用,每隔 time 调用一次。
使用setInterval()创建的定时器确保了定时器代码规则地插入队伍中。问题在于:如果定时器代码在代码再次添加到队列之前还没完成执行,结果就会导致定时器代码连续运行好几次。而之间没有间隔。不过幸运的是:javascript引擎足够聪明,能够避免这个问题。当且仅当没有该定时器的如何代码实例时,才会将定时器代码添加到队列中。这确保了定时器代码加入队列中最小的时间间隔为指定时间。
这种重复定时器的规则有两个问题:
- 某些间隔会被跳过
2 多个定时器的代码执行时间可能会比预期小。
以上是关于浅析javascript三种定时器原理和异同的主要内容,如果未能解决你的问题,请参考以下文章