JS定时器详解

前端定时器详解

一、简介

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(清除时用到);

  • 使用定时器时一定要先清除之前的定时器,避免定时器叠加;

猜你喜欢

转载自blog.csdn.net/IO14122/article/details/127549401