由一段代码进行正题:
console.log(1);
setTimeout(function(){
console.log(2)
},0);
console.log(3)
浏览器依次输出1,3,2,而不是看上去的1,2,3;
JS是单线程语言:JS在同一时间只能做一件事。
任务队列:分为同步任务和异步任务;任务队列有执行顺序,同步任务第一时间执行,同步任务执行完成后才能执行异步任务;
for(var i=0;i<3;i++){
setTimeout(function(){
console.log(i)
},1000)
}
运行上面的代码,浏览器会输出:3,3,3。
这段代码的原理在于,循环第一次的时候,执行setTimeout函数,但是因为setTimeout函数是异步任务,所以里面的语句都会被挂起不执行,循环第二次及之后的循环都是如此。那么此时setTimeout函数被放入异步队列,但是不执行,只有当这个异步时间到了规定的时间,函数体才会被执行。对于这个例子来说,for循环执行完毕,setTimeout函数依次被放入异步队列,然后过了1秒或2秒后,异步队列中的函数开始执行。
Event Loop:浏览器的JS引擎遇到setTimeout函数,识别这是一个异步任务,它不会把它放在运行栈中,它会把它拿走放进,拿走之后也不会立即放入异步队列中,先保留住,同步任务执行完后,到了setTimeout函数约定的时间,time模块会把它放入异步队列,浏览器同步任务执行完了,就会执行这个任务,它执行完后执行栈又空了,此时浏览器又会监听异步队列中是否有任务需要执行,如果有就会再拿出来执行,如此循环的过程就是Event Loop。
开启异步任务的条件:
setTimeout和setInerval
DOM事件
ES6中的Promise
浏览器假死现象的原理也是因为JS的单线程导致,如果同步任务一直在处理,浏览器就会卡住,做不了其它操作
网友评论