前端定时器详解
一、简介
JS是单线程,同一时间只能执行一个任务,其他任务就得排队,后续任务必须等到前一个任务结束才能开始执行。而有时候我们需要规定时间内做一件事,比如倒计时、页面轮播图等;这个时候就需要用到JS定时器。
当我们定义了一个定时器后,定时器会进入浏览器的定时器触发线程去排队,时间到了之后再转回到JS执行线程中排队。下面就介绍JS的几种定时器:
二、定时器
2.1 setTimeout(fn,time,lang)
在规定时间内执行一次,是一次性的。
fn是时间到了要执行的js代码串;
time执行代码钱需要等待的毫秒数;
lang可选,设置脚本语言JScript | VBScript | JavaScript(历史遗留问题可忽略此参数)
每次执行定时器函数会返回一个id,用于清除定时器:clearTimeout(timerId)
示例:
var timerId = setTimeout(function () { console.log("1秒钟到了"); clearTimeout(timerId); }, 1000);
2.2 setInterval(fn,time,lang)
在规定时间内执行,是周期性的。
fn是时间到了要执行的js代码串;
time执行代码钱需要等待的毫秒数;
lang可选,设置脚本语言JScript | VBScript | JavaScript(历史遗留问题可忽略此参数)
每次执行定时器函数会返回一个id,用于清除定时器:clearInterval(timerId)。只有清除这个定时器之后才会停止定时,否则便会一直执行。
示例:
var index = 0; var timerId = setInterval(function () { console.log(++index + "秒钟到了"); if(index === 10) { clearInterval(timerId); // 十秒的时候结束运行 } }, 1000);
2.3 requestAnimationFrame(fn)
触发间隔跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。默认只会执行一次,只需要传递fn执行代码串。清除定时器:cancelAnimationFrame(timerId)
这个是HTML5新增的特性,可以利用这个来做无限循环的动画,相比较setTimeout、setInterval的优势在于:
它会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,提升性能;
在隐藏或不可见的元素中,它不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量。
requestAnimationFrame(function() { console.log("屏幕刷新了!"); });
注意:requestAnimationFrame是新增的属性需要考虑兼容性,无法设置规定时间平常使用较少。
三、封装定时器类
在平常项目中很多地方都会用到这个定时功能,但是不能很好的清除对应定时器,导致事件不听调用,影响性能。当定义一个工具类后便可以轻松的创建一个定时任务,关闭时也不用担心定时id无法获取的问题。
class MyTimer { constructor() { this.timerId = undefined; } timeout(fn, time) { if(this.timerId) { clearTimeout(this.timerId) } setTimeout(fn, time); setInterval() } interval(fn, time) { if(this.timerId) { clearInterval(this.timerId) } setInterval(fn, time); } }
这里就是简单封装了一下,保证new的一个定时器都有唯一的一个id值;具体的封装需要根据业务场景来决定。
四、总结
主要定时器误差问题,受事件循环机制影响;
根据不同需求选择对应定时器;
用变量保存定时器返回的id(清除时用到);
使用定时器时一定要先清除之前的定时器,避免定时器叠加;
————————————————
版权声明:本文为CSDN博主「星星点点微光」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/IO14122/article/details/127549401