目录
JavaScript 执行机制
JavaScript 定时器
1、setTimeout()
2、setInterval()
3、setImmediate()
4、requestAnimationFrame()
5、clearTimeout() 取消定时器
6、 clearInterval()取消定时器
6、使用setTimeout模拟setInterval行为
setInterval与setInterval的区别
浏览器( JavaScript 引擎)执行 JavaScript 的机制是基于事件循环的。由于 JavaScript 是单线程,同一时间只能执行一个任务。为了避免某些长时间任务造成无意义等待,JavaScript 引入了异步概念。
同步任务直接在主线程队列中顺序执行,而异步任务会进入另一个任务队列,不会阻塞主线程。等到主线程队列空了(执行完了)的时候,就会去异步队列查询是否有可执行的异步任务了(异步任务通常进入异步队列之后还要等一些条件才能执行,如 ajax 请求、文件读写),如果某个异步任务可以执行了便加入主线程队列,以此循环。
定时器也是一种异步任务,通常浏览器都有一个独立的定时器模块,定时器的延迟时间就由定时器模块来管理,当某个定时器到了可执行状态,就会被加入主线程队列。
另外,多个定时器如不及时清除(clearTimeout()
),会造成干扰,使延迟时间更加捉摸不透。所以,不管定时器有没有执行完,要及时清除不需要的定时器。
设置一个定时器,在定时器到期后执行一次函数或代码段:setTimeout(fn, x) 表示延迟 x 毫秒之后执行 fn 。
var timeoutId = setTimeout(code, delay, param1, param2, ...)
var timeoutId = setTimeout(func, delay, param1, param2, ...)
- timeoutId 定时器ID
- func 延迟后执行的函数
- code 延迟后执行的代码字符串,不推荐使用
- delay 延迟的时间(单位:毫秒),默认值为0
- param1,param2 向延迟函数传递而外的参数,IE9以上支持
x
如果小于 4 ,会被当做 4 来处理。 不过不同浏览器的实现不一样,比如,Chrome可以设置1ms,IE11/Edge是4ms。setTimeout()
方法不是 Ecmascript 规范定义的内容,而是属于BOM提供的功能。setTimeout()
延迟也是有上限的,如果大于 2 的 31 次方的话,会立即执行,延迟无效。以固定的时间间隔重复调用一个函数或者代码段:
var intervalId = window.setInterval(func, delay , param1, param2, ...]);
var intervalId = window.setInterval(code, delay);
- intervalId 重复操作的ID
- func 延迟调用的函数
- code 代码段
- delay 延迟时间,没有默认值
对于 setInterval(fn, 100)
容易产生的误区:并不是上一次 fn
执行完了之后再过 100ms 才开始执行下一次 fn
。 事实上,setInterval
并不管上一次 fn
的执行结果,而是每隔 100ms 就将 fn
放入主线程队列,而两次 fn
之间具体间隔多久就不一定了,跟 setTimeout
实际延迟时间类似,和 JavaScript 执行情况有关。
在浏览器完全结束当前运行的操作之后立即执行指定的函数(仅 IE10 和 Node 0.10+ 中有实现),类似setTimeout(func, 0)
在IE11/Edge中,setImmediate()延迟可以在1ms以内,而setTimeout(0)有最低4ms的延迟,所以setImmediate()比setTimeout(0)更早执行回调函数。
该方法可以用来替代setTimeout(0)方法来滞后完成一些需要占用大量cpu时间的操作
下面的JavaScript可以用来兼容那些不支持setImmediate方法的浏览器:
if (!window.setImmediate) {
window.setImmediate = function(func, args){
return window.setTimeout(func, 0, args);
};
window.clearImmediate = window.clearTimeout;
}
专门为实现高性能的帧动画而设计的API,但是不能指定延迟时间,而是根据浏览器的刷新频率(帧)而定。
var requestId = window.requestAnimationFrame(func);
定义:阻止/取消 setTimeout() 方法设置的定时执行函数。
参数:id_of_settimeout是调用 setTimeout() 函数时所返回的ID值,使用该返回标识符作为参数,可以取消该 setTimeout() 所设定的定时执行操作。
注意: 要使用 clearTimeout(id_of_setinterval) 方法, 在创建执行定时操作时要使用全局变量:
var myVar = setTimeout(function(){ alert("Hello"); }, 3000);
clearTimeout(myVar);
定义: 可取消/停止由 setInterval() 函数设定的定时执行操作。
参数:id_of_setinterval是调用 setInterval() 函数时所返回的 ID 值,只有使用该返回标识符作为参数,才可以取消该 setInterval() 所设定的定时执行操作。
注意: 要使用 clearInterval() 方法, 在创建执行定时操作时要使用全局变量:
var myVar = setInterval(function(){ myTimer() }, 1000);
clearInterval(myVar);
通常情况下:递归的方式使用setTimeOut(),效果相当于使用setInterval()
好处:
//参数: 毫秒 需要执行的方法
function console1() {
console.log(111);
if(timer){
clearTimeout(timer);
}
timer = setTimeout(function(){
console1();
}, 3000);
}
console1()
setInterval
与setInterval
的区别如果是
setTimeout
和setInterval
的话,它俩仅仅在执行次数上有区别,setTimeout
一次、setInterval
n次。而通过
setTimeout
模拟的setInterval
与setInterval
的区别则在于:setTimeout
只有在回调完成之后才会去调用下一次定时器,而setInterval
则不管回调函数的执行情况,当到达规定时间就会在事件队列中插入一个执行回调的事件