你们可能都遇到过相似的面试题node
console.log(1);
setTimeout(()=>{
console.log(3)
},0);
console.log(2);
复制代码
结果输出为 1 2 3面试
为何结果不是1,3,2呢,咱们明明只设置了0毫秒的延迟,下面让咱们来看看究竟是怎么回事ajax
首先先用大白话简单介绍几个概念promise
咱们都知道js是单线程的,什么是单线程,说白了就是js在同一时间只能作一件事,这就是单线程浏览器
那么什么是任务队列呢,咱们都知道事件、ajax这些是异步操做,当我点击某个按钮时会经过回调函数执行某些操做,当我去请求接口的时候浏览器不用一直等着,它能够去作别的事情,当请求成功时会自动调起成功回调,那么这和js的单线程看起来是冲突的,那它又是怎么作到的呢,其实就是任务队列bash
说到任务队列这么还有概念,同步任务,异步任务, 像settimeout,ajax,promise这种就属于异步任务,像上述代码中的console.log(1)就属于同步任务网络
js代码是从上到下执行的,遇到异步任务要挂起,也就是说上面代码的settimeout会先挂起,先不执行,此时代码继续向下执行console.log(3),当同步任务都执行完成后才会去执行异步任务异步
因此刚才输出的结果是 1,2,3函数
下面咱们来看下一道题oop
console.log("a")
while(1){
}
console.log("b")复制代码
只打印出a, 由于都是同步任务,while循环会一直执行,全部打印不出来b
那么咱们再来看一道题
console.log("a");
setTimeout(()=>{
console.log("b")
},0);
while(1){}复制代码
仍是会只打印a,由于异步任务会当放到同步任务以后执行,因此b仍是打印不出来
接下来再看一道题
for(var i=0;i<4;i++){
setTimeout(()=>{
console.log(i)
},0)
}复制代码
最终会输出 4,4,4,4,for循环是一个同步任务,会先执行,此时会把setTimeout交给浏览器的time模块(主要是处理setTimeout,setInterval的),用不了1毫秒,循环执行完成,而此时r任务队列里尚未任务,只有setTimeout的时间(虽然咱们设置的是0,但浏览器最小大概是4毫秒)到了,浏览器的Time模块才会把setTimeout的回调函数放到任务队列里,任务队列再等待一个叫event loop(后面会讲) 的东西来执行,这道题讲的是异步任务的放入时间和执行的时间
什么是event loop
执行栈(stack)会执行同步任务,当遇到异步任务,浏览器的js引擎会将异步任务拿走,好比setTimeout,浏览器的time模块会将setTimeout拿走,当时间到了,会把回调函数放到任务队列(callback queue),当同步任务执行完成后,js引擎会去任务队列里看看有没有要执行的东西,发现里面有东西就会把它拿到执行栈中执行,此时setTimeout就变成了执行栈中的同步任务,当setTimeout执行完,执行栈又空了,js引擎会去任务队列中看看有没有其余须要执行的任务,如此往复的过程就是event loop
异步任务有哪些
setTimeout,setInterval
DOM事件
promise
MutationObserve
MessageChannel等
看下面代码
console.log(1);
setTimeout(function(){
console.log(2);
});
Promise.resolve(1).then(function(){
console.log('promise')
})复制代码
会输出 1 , promise , 2
由于异步任务中又分为宏任务和微任务
微任务包括
promise里的then,
MutationObserve
MessageChannel
宏任务包括
setTimeout,setInterval
在浏览器端微任务的执行会优先于宏任务,而在node里会怎么样呢
再来看一段代码
console.log(1);
setTimeout(function(){
console.log(2);
Promise.resolve(1).then(function(){
console.log('promise')
})
})
setTimeout(function(){
console.log(3);
})复制代码
在浏览器中会输出 1,2,promise,3
而用node运行则会输出 1,2,3,promise
在node中执行到相应的任务队列时,会把任务队列清空,里面的任务依次放到执行栈中执行,而后在去执行下一队列。
未完待续
若有错误,欢迎指正。图片均来自网络,侵删