背景:
1.数据展示页加一个自动刷新功能,让用户看到最新数据。
2.加个定时,过*(时间段)后执行,实现xx效果。
3.调整一下这几个事件响应的执行顺序等等。。。
复制代码
开发过程中我们常常要用到定时器去完成某些需求。js为我们准备了两个函数:setTimeout和setInterval,我们在进入主题之前,先简单介绍一下它们
1.setTimeout:
var timerId =setTimeout(function(){
//do
},delay)
2.setInterval
var timerId2 = setInterval(function() {
//do
}, delay)
//delay 时间周期
复制代码
首先,它们都会返回一个整数编号用来表示定时器。将这个值传给各自的clear方法可以取消定时。
其次,setTimeout是期望推迟(delay)ms后执行函数, setInterval则是期望间隔(delay)ms就执行一次函数。
为什么只是说期望那?上一个?瞧瞧
var start_date = 0;
setTimeout(function(){
var end_date = new Date().getTime()/1000
console.log('enter setTimeout date : ' + end_date)
console.log('time interval : ' + (end_date - start_date) + '秒')
},1000)
function bulky(){
start_date = new Date().getTime()/1000;
console.log("bulky start date : " + start_date)
for(var i=0;i<100000;i++){
for(var j=0;j<100000;j++){
var k = 0;
k = k*k;
}
}
}
bulky()
复制代码
先预测一下结果再运行代码,结果如下:
跟你想象中的结果一样吗?你会发现setTimeout并不是像它期望的那样----延迟1s就执行,而是要等待bulky()执行结束后才执行,这就是定时器不定时的情形。定时器是怎么实现定时的?为什么会出现不定时的情况?
首先,要明确的一点:javascript是以单线程的方式运行的。JavaScript的主要用途是与用户互动,以及操作DOM。若以多线程的方式,则可能出现冲突。假设有两个线程同时操作一个DOM元素,线程1要求浏览器删除DOM,而线程2却要求修改DOM样式,这时浏览器就无法决定采用哪个线程的操作。当然,我们可以为浏览器引入“锁”的机制来解决这些冲突,但大大提高复杂性,所以 JavaScript从诞生开始就选择了单线程执行。在某一时刻内只能执行特定的一个任务,并且会阻塞其它任务执行。
但是JavaScript 有个基于“Event Loop”并发的模型(不是并行)。前者是逻辑上的同时发生,而后者是物理上的同时发生。所以,单核处理器也能实现并发。
上图说明一下并发和并行:
再上图说明一下Event Loop
js既然是单线程的,也就意味着所有任务需要排队。所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)
-
同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务,形成了一个执行栈(execution context stack)
-
异步任务指的是,不进入主线程,而进入"任务队列"(task queue)的任务。"任务队列"是一个事件的队列(可以当作消息的队列来理解)。IO设备完成一项任务or异步任务有了运行结果,就在"任务队列"中添加一个事件,表示相关的操作可以进入"执行栈",就等着执行栈调用了。
参照Event Loop的图,说一下大致的流程----> 执行栈中流式执行函数(同步任务),可能会调用API在任务队列中加入事件(onlick,onload等等)但并不执行。只有当前执行栈没有其他操作时,任务队列才会入执行栈中,执行
原理讲完了,回到正题。因为setTimeout, setInterval是异步任务,调用之后不会直接进入执行栈,而是进入任务队列,所以只有等到当前执行栈没有其他操作,它们才会进入执行栈中执行, 以上就是为什么定时器不总是定时的原因了。
哦,对了如果delay时间周期设为0,相当于一个插队操作
举例
?献上:
function f1(){
console.log('f1')
}
function f2(){
console.log('f2')
}
function f3(){
console.log('f3')
setTimeout(function(){
console.log('setTimeout1')
},2000)
}
setTimeout(function(){
console.log('setTimeout2')
},3000)
setTimeout(function(){
console.log('setTimeout3')
},1000)
setTimeout(function(){
console.log('setTimeout4')
},0)
f1()
f2()
f3()
复制代码
运行结果
好了,以上内容就是我对js定时器的认识,希望可以帮助到你未经本人允许,不得转载。文章有疏漏浅薄之处,请各位大神斧正