淺析 JS 中的 EventLoop 事件循環(新手向)

Event Loop 這個概念相信你們或多或少都瞭解過,可是有一次被一個小夥伴問到它具體的原理的時候,感受本身只知道個大概印象,因而計劃着寫一篇文章,用輸出倒逼輸入,讓本身從新學習這個概念,同時也能幫助更多的人理解它~javascript

概念

JavaScript 是一門 單線程 語言,即同一時間只能執行一個任務,即代碼執行是同步而且阻塞的。html

eg. 這就像只有一個窗口的銀行,客戶須要一個一個排隊辦理業務。java

只能同步執行確定是有問題的,因此 JS 有了一個用來實現異步的函數:setTimeout網絡

下面要講的 Event Loop 就是爲了確保 異步代碼 能夠在 同步代碼 執行後繼續執行的。數據結構

因爲涉及到的相關概念較多,咱們先從最簡單的來。異步

隊列(Queue)

隊列 是一種 FIFO(First In, First Out) 的數據結構,它的特色就是 先進先出函數

eg. 生活中最多見的例子就是排隊啦,排在隊伍最前面的人最早被提供服務。oop

棧(Stack)

是一種 LIFO(Last In, First Out)的數據結構,特色即 後進先出post

eg. 你們都吃過桶裝薯片吧~薯片在包裝的時候只能從頂部放入,而吃的時候也只能從頂部拿出,這就叫後進先出哈學習

調用棧(Call Stack)

棧咱們已經知道了,那麼什麼是 調用棧 呢 ?

它本質上固然仍是個棧啦 廢話,關鍵在於它裏面裝的東西,是一個個待執行的函數。

Event Loop 會一直檢查 Call Stack 中是否有函數須要執行,若是有,就從棧頂依次執行。同時,若是執行的過程當中發現其餘函數,繼續入棧而後執行。
複製代碼

先拿兩個函數來講:

  • 棧空
  • 如今執行到一個 函數A,函數A 入棧
  • 函數A 又調用了 函數B,函數B 入棧
  • 函數B 執行完後 出棧
  • 而後繼續執行 函數A,執行完後A也 出棧
  • 棧空

更復雜一點的話,來看一段代碼:

call-stack-code.png

這段代碼在 調用棧中的運行順序以下圖:

call-stack-process.png

這個調用棧其實你們常常會見到,就是在控制檯報錯的時候,錯誤信息顯示的就是當前時刻調用棧的狀態。

But, 上面咱們討論的其實都是同步代碼,代碼在運行的時候只用 調用棧 解釋就能夠了。

那麼,假如咱們發起了一個網絡請求(request),或者設置了一個定時器延時(setTimeout),一段時間後的代碼(回調函數)確定不是直接被加到調用棧吧?

這時就要引出 事件表格(Event Table)事件隊列 (Event Queue)

Event Table

Event Table 能夠理解成一張 事件->回調函數 對應表

它就是用來存儲 JavaScript 中的異步事件 (request, setTimeout, IO等) 及其對應的回調函數的列表

Event Queue

Event Queue 簡單理解就是 回調函數 隊列,因此它也叫 Callback Queue

當 Event Table 中的事件被觸發,事件對應的 回調函數 就會被 push 進這個 Event Queue,而後等待被執行

Event Loop

先來看一個流程圖:

event-loop-process.png

  • 開始,任務先進入 Call Stack
  • 同步任務直接在棧中等待被執行,異步任務從 Call Stack 移入到 Event Table 註冊
  • 當對應的事件觸發(或延遲到指定時間),Event Table 會將事件回調函數移入 Event Queue 等待
  • 當 Call Stack 中沒有任務,就從 Event Queue 中拿出一個任務放入 Call Stack

Event Loop 指的就是這一整個圈圈:

它不停檢查 Call Stack 中是否有任務(也叫棧幀)須要執行,若是沒有,就檢查 Event Queue,從中彈出一個任務,放入 Call Stack 中,如此往復循環。


好啦,不知道有沒有看明白呢?放一張更經典的圖:

event-loop.png

其中與 Event Queue 對應的還有一個叫 Job Queue,它主要是用來執行 Promise 的,這兩種 Queue 有什麼區別呢?

這就涉及到 宏任務 (macro task) 和 微任務 (micro task) 了,咱們放在下篇再講~

參考文章

原文連接

MDN EventLoop

javascript-event-loop

understanding-js-the-event-loop

這一次,完全弄懂JavaScript執行機制

understanding-event-loop-call-stack-event-job-queue-in-javascript

歡迎關注個人公衆號:碼力全開

相關文章
相關標籤/搜索