1. 程式人生 > >javascript的巨集任務和微任務

javascript的巨集任務和微任務

今天進行了人生中的第一次面試。結果涼涼了。但是還是學到了很多東西。其中在面試時面試官問了我一道題

setTimeout(function(){
		    console.log('1')
		});

		new Promise(function(resolve){
		    console.log('2');
		}).then(function(){
		    console.log('3')
		});

		console.log('4');

請你給出這段程式碼的執行順序。當時我就蒙犢子了。同步非同步我看過很多的講解,大多都是要麼你就一個setTimeout函式,要麼就一個Promise函式。兩個函式放到一起的我還真沒見過。於是我就想:

settimeout肯定是非同步的。 我也知道有一個event佇列,你settimeout沒設定時間應該直接就進入這個隊列了吧,然後就是Promise的回掉函式進入event佇列。 當時我二話不說給了個答案 2,4,1,3.並且很自信。然後面試官就問你不想想了?我說不想了。然後後半段他全程開始皺眉頭了。我也涼涼。最後他讓我回去看一下巨集任務和微任務。

首先說一下普通的非同步函式的執行過程吧:

同步和非同步任務分別進入不同的執行"場所",同步的進入主執行緒,非同步的進入Event Table並註冊函式。當指定的事情完成時,Event Table會將這個函式移入Event Queue。主執行緒內的任務執行完畢為空,會去Event Queue讀取對應的函式,進入主執行緒執行。上述過程會不斷重複,也就是常說的Event Loop(事件迴圈)。

圖文我是轉載的一個掘金的老哥的文章裡的。他叫:ssssyokissssyoki

那麼如此看來我給的答案還是對的。但是js非同步有一個機制,就是遇到巨集任務,先執行巨集任務,將巨集任務放入eventqueue,然後在執行微任務,將微任務放入eventqueue最騷的是,這兩個queue不是一個queue。當你往外拿的時候先從微任務裡拿這個回掉函式,然後再從巨集任務的queue上拿巨集任務的回掉函式。 我當時看到這我就服了還有這種騷操作。

再盜個圖


而巨集任務一般是:包括整體程式碼script,setTimeout,setInterval。

微任務:Promise,process.nextTick。

記住就行了。

然後回到開頭的程式碼。因為settimeout是巨集任務,雖然先執行的他,但是他被放到了巨集任務的eventqueue裡面,然後程式碼繼續往下檢檢視有沒有微任務,檢測到Promise的then函式把他放入了微任務序列。等到主線程序的所有程式碼執行結束後。先從微任務queue裡拿回掉函式,然後微任務queue空了後再從巨集任務的queue拿函式。

所以正確的執行結果當然是:2,4,3,1。

如果還是不懂得同學可以去看一下這個老哥的文章,總結的挺到位的。向他學習。點選開啟連結