天天看點

Event Loop、 宏任務和微任務

本文将介紹我自己對JS

Event Loop

宏任務、微任務

的了解。

二話不說先上圖:

Event Loop、 宏任務和微任務

接下來将會針對此圖講解什麼是Event Loop 什麼事宏任務和微任務(其實聰明的你們通過圖大體也能了解的是吧~),再此之前先簡單介紹幾個概念。

為何js是單線程

JavaScript的單線程,與它的用途有關。作為浏覽器腳本語言,JavaScript的主要用途是與使用者互動,以及操作DOM。這決定了它隻能是單線程,否則會帶來很複雜的同步問題。比如,假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加内容,另一個線程删除了這個節點,這時浏覽器應該以哪個線程為準?

是以,為了避免複雜性,從一誕生,JavaScript就是單線程,這已經成了這門語言的核心特征,将來也不會改變。

為了利用多核CPU的計算能力,HTML5提出 Web Worker 标準,允許JavaScript腳本建立多個線程,但是子線程完全受主線程控制,且不得操作DOM。是以,這個新标準并沒有改變JavaScript單線程的本質。(此段來自阮老師)

概念

  • 同步任務:在主線程上排隊執行的任務,隻有前一個任務執行完畢,才能執行後一個任務。
  • 異步任務:不進入主線程、而進入

    任務隊列

    (Task Queue)的任務。
  • 任務隊列:是一個事件的隊列(也可以了解成消息的隊列),IO裝置完成一項任務,就在"任務隊列"中添加一個事件,表示相關的異步任務可以進入"執行棧"了。主線程讀取"任務隊列",就是讀取裡面有哪些事件。

詳解圖示

  1. 當一段代碼在主線程執行時,會有同步任務和異步任務,異步任務會判斷是微任務還是宏任務,進行不同處理。然後繼續執行目前主線程内的代碼,直到結束。此段主線程執行的的為宏任務。
  2. 接着上面的判斷,宏任務的異步操作會先進入

    Event Table

    執行,然後當執行結束會把回調函數推入到

    Event Queue

    ,然後等待主線程的結束。對于微任務的異步會推入到另外一個

    Event Queue

    ,等待主線程的結束。
  3. 當主線程結束後,先執行所有的微任務,然後執行把宏任務的任務隊列(

    Event Queue

    )中的event拉到主線程執行。
  4. 一直循環前面的操作。至此你應該懂的

    EventLoop

    了。

    備注:如果在執行 microtask(微任務) 的過程中,又産生了microtask,那麼會加入到隊列的末尾,也會在這個周期被調用執行。

舉個例子