瀏覽器事件循環,基礎面試中大部分都會問的,本文講講這個知識點。html
事件循環是負責執行代碼、收集和處理事件以及執行隊列中的子任務的一套機制。html5
在事件循環機制中,使用的棧數據結構即是執行上下文棧,每當有函數被調用時,便會建立相對應的執行上下文並將其入棧;使用到堆數據結構主要是爲了表示一個大部分非結構化的內存區域存放對象;使用到的隊列數據結構即是任務隊列,主要用於存放異步任務。以下圖:面試
在JavaScript代碼運行過程當中,會進入到不一樣的執行環境中,一開始執行時最早進入到全局環境,此時全局上下文首先被建立併入棧,以後當調用函數時則進入相應的函數環境,此時相應函數上下文被建立併入棧,當處於棧頂的執行上下文代碼執行完畢後,則會將其出棧。這裏說的棧就是執行上下文。瀏覽器
在事件循環機制中,存在多種任務隊列,其分爲宏任務隊列和微任務隊列兩種。微信
宏任務包括setTimeout、setInterval、I/O、UI rendering。數據結構
微任務包括Promise、Object.observe(已廢棄)、MutationObserver(html5新特性)。異步
主線程執行JavaScript總體代碼,造成執行上下文棧,當遇到各類任務源時將其所指定的異步任務掛起,接受到響應結果後將異步任務放入對應的任務隊列中,直到執行上下文棧只剩全局上下文;函數
將微任務隊列中的全部任務隊列按優先級、單個任務隊列的異步任務按先進先出的方式入棧並執行,直到清空全部的微任務隊列;操作系統
將宏任務隊列中優先級最高的任務隊列中的異步任務按先進先出的方式入棧並執行;線程
重複第 2 3 步驟,直到清空全部的宏任務隊列和微任務隊列,全局上下文出棧。
簡單來講,事件循環機制的流程就是,主線程執行JavaScript總體代碼後將遇到的各個任務源所指定的任務分發到各個任務隊列中,而後微任務隊列和宏任務隊列交替入棧執行直到清空全部的任務隊列,全局上下文出棧。
雖然Node.js也有事件循環,但是它和瀏覽器的事件循環徹底不是一個東西。Node.js採用V8做爲js的解析引擎,而I/O處理方面使用了本身設計的libuv,libuv是一個基於事件驅動的跨平臺抽象層,封裝了不一樣操做系統一些底層特性,對外提供統一的API,事件循環機制也是它裏面的實現。這裏不展開講了,想了解的本身去看文檔。
謝謝閱讀!
須要加微信交流,可留言!