事件迴圈與任務佇列

王振宇發表於2019-03-26

講事件迴圈和任務佇列,肯定就要先說一下JavaScript的單執行緒

因為JavaScript(最初)是執行在瀏覽器中的,作為一個與使用者互動為主的語言,如果設計為多執行緒,會帶來很複雜的同步問題,比如兩個事件,一個給變數a*2,一個給變數a+10,如果存在多執行緒,執行順序不同,結果不同,同樣的情況應用於DOM操作呢,所以為了避免這種複雜性,JavaScript設計為單執行緒

單執行緒帶來的新問題就是程式中有很多操作會很耗時,比如Ajax請求,而為了這種操作不阻塞程式的執行,所以有了任務佇列。用途就是瀏覽器發起一個Ajax請求,而從發起請求到收到響應是需要一段時間的,這時主執行緒會把這個任務掛起,執行接下來的任務,以保證程式不被阻塞,待到收到請求的響應,再把對應的回撥方法新增到一個佇列中去依次執行。簡單理解這個佇列就是任務佇列。

接下來上圖:

事件迴圈與任務佇列

解釋下上圖:

瀏覽器的中的任務分為巨集任務微任務,所以任務佇列也分為巨集任務佇列微任務佇列

巨集任務佇列中根據事件源又分為如圖所示任務佇列(新新增一個巨集任務的時候,如果巨集任務佇列中有該事件源的佇列,則新增到該佇列,否則建立該事件源的佇列,把該巨集任務插入佇列,並把該佇列插入巨集任務佇列),因為主執行緒每次會執行微任務佇列中的所有微任務,所以微任務中不會根據事件源劃分微任務佇列,主執行緒中所有同步任務執行完畢後,會執行微任務佇列中所有的微任務,然後執行一個巨集任務佇列,再次執行微任務佇列中的所有微任務,再執行下一個巨集任務佇列,如此迴圈,這個過程就是事件迴圈Event Loop)。

如果有錯誤或者不嚴謹的地方,請給予指正,十分感謝!



相關文章