js定时器,你所要了解的那点事

背景:

1.数据展现页加一个自动刷新功能,让用户看到最新数据。 
2.加个定时,过*(时间段)后执行,实现xx效果。
3.调整一下这几个事件响应的执行顺序等等。。。
复制代码

开发过程当中咱们经常要用到定时器去完成某些需求。js为咱们准备了两个函数:setTimeout和setInterval,咱们在进入主题以前,先简单介绍一下它们javascript

1.setTimeout:
var timerId =setTimeout(function(){
    //do    
},delay)

2.setInterval
var timerId2 = setInterval(function() {
    //do
}, delay)
//delay 时间周期
复制代码

首先,它们都会返回一个整数编号用来表示定时器。将这个值传给各自的clear方法能够取消定时。java

其次,setTimeout是指望推迟(delay)ms后执行函数, setInterval则是指望间隔(delay)ms就执行一次函数。浏览器

为何只是说指望那?上一个🌰瞧瞧bash

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”并发的模型(不是并行)。前者是逻辑上的同时发生,然后者是物理上的同时发生。因此,单核处理器也能实现并发。异步

上图说明一下并发和并行:async

再上图说明一下Event Loop函数

js既然是单线程的,也就意味着全部任务须要排队。全部任务能够分红两种,一种是同步任务(synchronous),另外一种是异步任务(asynchronous)oop

  • 同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务,造成了一个执行栈(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定时器的认识,但愿能够帮助到你

未经本人容许,不得转载。文章有疏漏浅薄之处,请各位大神斧正

相关文章
相关标签/搜索