JS提供了一些原生方法来实现延时去执行某一段代码,下面来简单介绍一下setTiemout、setInterval、setImmediate、requestAnimationFrame。

一、什么是定时器

JS提供了一些原生方法来实现延时去执行某一段代码

setTimeout:

设置一个定时器,在定时器到期后执行一次函数或代码段

var timeoutId = window.setTimeout(func[, delay, param1, param2, …]); var timeoutId = window.setTimeout(code[, delay]);

var timeoutId;

timeoutId = setTimeout(function () {

console.log(1);

}, 300);

setTimeout(function () {

clearTimeout(timeoutId); //清除定时器

console.log(2);

}, 100);

setTimeout('console.log("5")', 400);

// 分别输出: 2、4

timeoutId: 定时器ID func: 延迟后执行的函数 code: 延迟后执行的代码字符串,不推荐使用原理类似eval() delay: 延迟的时间(单位:毫秒),默认值为0 param1,param2: 向延迟函数传递而外的参数,IE9以上支持

setInterval:

以固定的时间间隔重复调用一个函数或者代码段

var intervalId = window.setInterval(func, delay[, param1, param2, …]); var intervalId = window.setInterval(code, delay);

var intervalId;

intervalId = setInterval(function () {

console.log(4);

clearInterval(intervalId); //清除定时器

}, 200);

intervalId: 重复操作的ID func: 延迟调用的函数 code: 代码段 delay: 延迟时间,没有默认值

setImmediate:

在浏览器完全结束当前运行的操作之后立即执行指定的函数(仅IE10和Node 0.10+中有实现),类似setTimeout(func, 0)

var immediateId = setImmediate(func[, param1, param2, …]); var immediateId = setImmediate(func);

immediateId: 定时器ID func: 回调

requestAnimationFrame:

专门为实现高性能的帧动画而设计的API,但是不能指定延迟时间,而是根据浏览器的刷新频率而定(帧)

var requestId = window.requestAnimationFrame(func); func: 回调

上面简单的介绍了四种JS的定时器,而本文将会主要介绍比较常用的两种:setTimeout和setInterval。

二、setInterval 和 setTimeout的区别?

1、在执行次数上有区别,setTimeout一次、setIntervaln次。 2、通过setTimeout模拟的setInterval与setInterval的区别则在于:setTimeout只有在回调完成之后才会去调用下一次定时器,而setInterval则不管回调函数的执行情况,当到达规定时间就会在事件队列中插入一个执行回调的事件,所以在选择定时器的方式时需要考虑setInterval的这种特性是否会对你的业务代码有什么影响?

三、JS定时器的工作原理

这里将用引用How JavaScript Timers Work中的例子来解释定时器的工作原理,该图为一个简单版的原理图。

Timers 上图中,左侧数字代表时间,单位毫秒;左侧文字代表某一个操作完成后,浏览器去询问当前队列中存在哪些正在等待执行的操作;蓝色方块表示正在执行的代码块;右侧文字代表在代码运行过程中,出现哪些异步事件。该图大致流程如下:

程序开始时,有一个JS代码块开始执行,执行时长约为18ms,在执行过程中有3个异步事件触发,其中包括一个setTimeout、鼠标点击事件、setInterval第一个setTimeout先运行,延迟时间为10ms,稍后鼠标事件出现,浏览器在事件队列中插入点击的回调函数,稍后setInterval运行,10ms到达之后,setTimeout向事件队列中插入setTimeout的回调当第一个代码块执行完成后,浏览器查看队列中有哪些事件在等待,他取出排在队列最前面的代码来执行在浏览器处理鼠标点击回调时,setInterval再次检查到到达延迟时间,他将再次向事件队列中插入一个interval的回调,以后每隔指定的延迟时间之后都会向队列中插入一个回调后面浏览器将在执行完当前队头的代码之后,将再次取出目前队头的事件来执行

这里只是对定时器的原理做一个简单版的描述,实际的处理过程比这个复杂。

四、需要注意的点

setTimeout有最小时间间隔限制,HTML5标准为4ms,小于4ms按照4ms处理,但是每个浏览器实现的最小间隔都不同因为JS引擎只有一个线程,所以它将会强制异步事件排队执行(生成一个定时器,将回调插入到事件队列中,等待当前队列中无任务执行时立即执行。)如果setInterval的回调执行时间长于指定的延迟,setInterval将无间隔的一个接一个执行 this的指向问题可以通过bind函数、定义变量、箭头函数的方式来解决

五、参考

MDN How JavaScript Timers Work JavaScript定时器与执行机制解析

钓鱼主线和子线怎么绑
前打竿用什么轮子比较好?