你不知道的Event Loop

鈞嘢嘢發表於2018-01-26

關於Event Loop網上有很多文章都有講解,包括我自己也有幾篇文章有講述event loop相關內容。之前寫了一篇文章總結了Nodejs中event loop的原理,這裡的event loop指的是服務端nodejs的event loop。此外,另一篇文章中有講到前端瀏覽器中event loop的執行過程(4.Event Loop & Callback)。

顯然,這裡出現了兩個event loop,那麼這裡說到的兩個event loop是不是一回事,是不是相同的東西呢?

事實上,這兩個是不完全相同的。一個歸屬於前端瀏覽器中,一個歸屬於nodejs後端服務中。但很多文章在講event loop的時候並木有區分具體是說的哪個,大多數是以一個籠統的概念在解釋event loop,所以很多細節仔細想想老是有不明白的地方。

今天在Quora上看到一篇相關的回答覺得說的挺清楚的。加上自己的理解和查閱相關資料,總結如下。

Event loop in Front-End

前端環境中實際上說的就是瀏覽器環境,那麼首先得搞清楚瀏覽器中跟執行JS程式碼相關的有哪些東西。

  • core JS engine(我們熟悉的V8引擎,即JS interpreter)
  • web environment(如排版引擎,渲染引擎等)Browser更加詳細內容請檢視這裡

1. core JS engine

JS引擎是實現了ECMAScript標準,在該標準中,並未提及event loop,說明標準中並不要求需要有event loop。

但像setTimeout()setInterval()這些方法的回撥函式是儲存在任務佇列中的,再由event loop輪詢佇列放到執行棧中執行,這在很多文章中都有提及。

這說明瀏覽器中的event loop並不是由JS引擎(如V8)提供,而是由瀏覽器的其他部件提供的。

關於setTimeout()setInterval()這些Timer相關的規範,其實並不屬於ECMAScript標準,關於是否納入該標準其實一直都在爭論中,但到目前為止還沒有納入。

那麼有人要問了,那我們寫JS程式碼不是經常用這些方法嗎?確實是,因為它們是在W3C標準中定義了,它是屬於browser environment中的window物件的方法(window.setTimeout)。這就是後面要將的Web Environment。

2. Web Environment

這裡web environment包含了DOM API,XMLHttpRequest,setTimeout()等 Web標準中規範的東西。Front-End中提到的event loop也是由web environment提供的,具體的可以參考W3C中的規範。這裡說到:

There is also at most one event loop per unit of related similar-origin browsing contexts (though several units of related similar-origin browsing contexts can have a shared event loop).

從中可以知道每個browsing context至多有一個event loop。

再回顧下瀏覽器中event loop的這張圖:

browser enent loop

結合上述所講,再看這張圖就清晰很多了,左邊代表JS引擎(core JS engine),這裡的event loop是所屬在web environment中,輪詢呼叫任務佇列中的js程式碼扔給JS引擎中執行。我們程式碼中的setTimeout()ajax請求,DOM操作等是呼叫web environment中的Web API進行呼叫。

Event Loop in NodeJS

在NodeJs中,event loop也是隻有一個,也即是主執行緒,是一直執行的。與分析瀏覽器一樣,這裡也先搞清楚NodeJS中都有些什麼東西。這裡直接給出一張圖:

nodejs

可以看到,與瀏覽器一樣,Nodejs中也同樣採用了JS引擎(這裡是V8)作為JS的編譯器,同時通過Libuv這個庫提供了讀取檔案、網路資源請求等I/O操作。

NodeJS中的event loop也正是由Libuv提供的,關於nodejs中的event loop細節部分這裡不再贅述,詳細內容可以看Node.js design pattern : Reactor (Event Loop)這篇文章。

總結

  • NodeJs的event loop由Libuv提供。
  • 瀏覽器中的event loop由browsing context提供。
  • 兩者並不是一回事,不要混為一談。

相關文章