關於Event Loop網上有不少文章都有講解,包括我本身也有幾篇文章有講述event loop相關內容。以前寫了一篇文章總結了Nodejs中event loop的原理,這裏的event loop指的是服務端nodejs的event loop。此外,另外一篇文章中有講到前端瀏覽器中event loop的執行過程(4.Event Loop & Callback)。html
顯然,這裏出現了兩個event loop,那麼這裏說到的兩個event loop是否是一回事,是否是相同的東西呢?前端
事實上,這兩個是不徹底相同的。一個歸屬於前端瀏覽器中,一個歸屬於nodejs後端服務中。但不少文章在講event loop的時候並木有區分具體是說的哪一個,大多數是以一個籠統的概念在解釋event loop,因此不少細節仔細想一想總是有不明白的地方。html5
今天在Quora上看到一篇相關的回答以爲說的挺清楚的。加上本身的理解和查閱相關資料,總結以下。node
前端環境中實際上說的就是瀏覽器環境,那麼首先得搞清楚瀏覽器中跟執行JS代碼相關的有哪些東西。web
JS引擎是實現了ECMAScript標準,在該標準中,並未說起event loop,說明標準中並不要求須要有event loop。ajax
但像setTimeout()
,setInterval()
這些方法的回調函數是保存在任務隊列中的,再由event loop輪詢隊列放到執行棧中執行,這在不少文章中都有說起。後端
這說明瀏覽器中的event loop並非由JS引擎(如V8)提供,而是由瀏覽器的其餘部件提供的。api
關於setTimeout()
,setInterval()
這些Timer
相關的規範,其實並不屬於ECMAScript標準,關因而否歸入該標準其實一直都在爭論中,但到目前爲止尚未歸入。瀏覽器
那麼有人要問了,那咱們寫JS代碼不是常常用這些方法嗎?確實是,由於它們是在W3C標準中定義了,它是屬於browser environment中的window對象的方法(window.setTimeout
)。這就是後面要將的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的這張圖:
結合上述所講,再看這張圖就清晰不少了,左邊表明JS引擎(core JS engine),這裏的event loop是所屬在web environment中,輪詢調用任務隊列中的js代碼扔給JS引擎中執行。咱們代碼中的setTimeout()
,ajax
請求,DOM操做等是調用web environment中的Web API進行調用。
在NodeJs中,event loop也是隻有一個,也便是主線程,是一直運行的。與分析瀏覽器同樣,這裏也先搞清楚NodeJS中都有些什麼東西。這裏直接給出一張圖:
能夠看到,與瀏覽器同樣,Nodejs中也一樣採用了JS引擎(這裏是V8)做爲JS的編譯器,同時經過Libuv這個庫提供了讀取文件、網絡資源請求等I/O操做。
NodeJS中的event loop也正是由Libuv提供的,關於nodejs中的event loop細節部分這裏再也不贅述,詳細內容能夠看Node.js design pattern : Reactor (Event Loop)這篇文章。