JavaScript之事件循環,宏任務與微任務


事件循環 Event Loop

程序中設置兩個線程:一個負責程序本身的運行,稱為"主線程";另一個負責主線程與其他進程(主要是各種I/O操作)的通信,被稱為"Event Loop線程"(可以譯為"消息線程")。

所有任務可以分成兩種,一種是同步任務(synchronous),另一種是異步任務(asynchronous)。同步任務指的是,在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行后一個任務;異步任務指的是,不進入主線程、而進入"任務隊列"(task queue)的任務,只有"任務隊列"通知主線程,某個異步任務可以執行了,該任務才會進入主線程執行。

事件循環具體過程就是:

  • 同步任務進入主線程,異步任務進入Event Table並注冊函數。
  • 當異步任務完成時,Event Table會將這個函數移入Event Queue。
  • 主線程內的任務執行完畢執行棧為空,會去Event Queue讀取對應的函數,進入主線程執行。
  • 上述過程會不斷重復,也就是常說的Event Loop(事件循環)。

具體的例子:

console.log('Hi');
setTimeout(function() {
  console.log('callback');
}, 0);
console.log('Bye');

//Hi,Bye,callback

事件循環不太理解的可以去看這篇有動圖解釋:https://www.jb51.net/article/133424.htm

宏任務與微任務

在JavaScript中,任務被分為兩種,一種宏任務(MacroTask),一種叫微任務(MicroTask)。

MacroTask(宏任務)

宿主環境提供的(瀏覽器和node)

  • script全部代碼、setTimeoutsetInterval

MicroTask(微任務)

語言標准提供的

  • Promise、await

宏任務與微任務執行順序:

  • 執行棧在執行完同步任務后,查看執行棧是否為空,如果執行棧為空,就會去檢查微任務隊列是否為空,如果為空的話,就執行宏任務,否則就一次性執行完所有微任務。
  • 每次單個宏任務執行完畢后,檢查微任務隊列是否為空,如果不為空的話,會按照先入先出的規則全部執行完微任務后,設置微任務隊列為null,然后再執行宏任務,如此循環。

總結:同步—>微任務—>宏任務

常見異步任務類型

  • settimeout的回調函數放到宏任務隊列里,等到執行棧清空以后執行
  • promise本身是同步的立即執行函數(同步)
  • promise.then里的回調函數會放到相應宏任務的微任務隊列里,等宏任務里面的同步代碼執行完再執行;
  • async函數表示函數里面可能會有異步方法,await后面跟一個表達式,async方法執行時,遇到await會立即執行表達式,然后把await表達式后面的代碼放到微任務隊列里,讓出執行棧讓同步代碼先執行
new Promise(function(resolve){
    console.log('1');
    resolve();
}).then(function(){
    console.log('2')
});

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

console.log('4');
//1,4,2,3

參考:https://www.cnblogs.com/dajuyiding/p/11355677.html

http://www.ruanyifeng.com/blog/2014/10/event-loop.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM