你們可能都遇到過相似的面試題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中執行到相應的任務隊列時,會把任務隊列清空,裏面的任務依次放到執行棧中執行,而後在去執行下一隊列。
未完待續
若有錯誤,歡迎指正。圖片均來自網絡,侵刪