1. 程式人生 > 程式設計 >關於js的事件迴圈機制剖析

關於js的事件迴圈機制剖析

前言

眾所周知, javascript是單執行緒這一核心,可是瀏覽器又能很好的處理非同步請求,那麼到底是為什麼呢?其中的原www.cppcns.com理與事件迴圈機制大有關係。

在探索事件迴圈之前,我們得先了解瀏覽器執行執行緒~~

瀏覽器的渲染程序是多執行緒的,瀏覽器每一個tab標籤都代表一個獨立的程序,其中瀏覽器核心屬於瀏覽器多程序中的一種,主要負責頁面渲染,指令碼執行,事件處理等。其包含的執行緒有以下幾種

GUI 渲染執行緒:負責渲染頁面,解析 HTML,css 構成 DOM 樹;
js 引擎執行緒:解釋執行程式碼、使用者輸入和網路請求;
事件處理執行緒:click、mouse等互動事www.cppcns.com

件發生後將事件函式放入佇列;
定時器觸發執行緒:等時間結束後執行函式推入任務佇列中;
http網路請求執行緒:處理使用者的get、post請求,返回結程式設計客棧果推入任務佇列中。

瞭解了瀏覽器渲染流程,還要了解JS的執行機制。JS的執行機制就是事件迴圈

執行棧

JS執行的環境稱之為宿主環境。

執行棧:call stack,一個數據結構,用於存放各種函式的執行環境,每一個函式執行之前,它的相關資訊會加入到執行棧。函式呼叫之前,建立執行環境,然後加入到執行棧;函式呼叫之後,銷燬執行環境。

關於js的事件迴圈機制剖析

事件迴圈

js中所有的任務可以分為同步任務和非同步任務,同步任務是立即執行的任務,同步任務一般會直接進入到主執行緒中執行;而非同步任務,就是非同步執行的任務,比如ajax網路請求,setTimeout 定時函式等都屬於非同步任務,非同步任務會通過任務佇列(先進先出)的機制來進行協調。同步和非同步任務分別進入不同的執行環境,同步的進入主執行緒,即主執行棧,非同步的進入任務佇列。主執行緒內的任務執行完畢為空,會去任務佇列讀取對應的任務,推入主執行緒執行。 這種不斷重複就是我們說的 Event Loop (事件迴圈)。具體流程如下圖。

關於js的事件迴圈機制剖析

在事件迴圈中,每進行一次迴圈操作稱為tick,每一次 tick 的任務鍵的步驟可以總結如下:1.執行一個巨集任務(棧中沒有就從事件佇列中獲取);2.執行過程中如果遇到微任務,就將它新增到微任務的任務佇列中;3.巨集任務執行完畢後,立即執行當前微任務佇列中的所有微任務(依次執行);4.當前巨集任務執行完畢,開始檢查渲染,然後GUI執行緒接管渲染;5.渲染完畢後,JS執行緒繼續接管,開始下一個巨集任務(從事件佇列中獲取)

關於js的事件迴圈機制剖析

巨集任務主要包含:script( 整體程式碼)、setTimeoutdHGhQB、setInterval、I/O、UI 互動事件、setImmediate(Node.js 環境)

微任務主要包含:Promise、MutaionObserver、process.nextTick(Node.js 環境)

事件迴圈例子

console.log('script start');
//整體 script 作為第一個巨集任務進入主執行緒,遇到 console.log,輸出 script start
setTimeout(function() {
  console.log('setTimeout');
},0);
//遇到 setTimeout,其回撥函式被分發到巨集任務 Event Queue 中
Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});
//遇到 Promise,其 then函式被分到到微任務 Event Queue 中,記為 then1,之後又遇到了 then 函式,將其分到微任務 Event Queue 中,記為 then2
console.log('script end');
//遇到 console.log,輸出 script end

如此,Event Queue(事件佇列)中存在三個任務:巨集任務:setTimeout 微任務:then1、then2。執行微任務首先then1,輸出 promise1,然後執行 then2,輸出 promise2,這樣就清空了所有微任務dHGhQB

執行 setTimeout 任務,輸出 setTimeout 至此,輸出的順序是:script start,script end,promise1,promise2,setTimeout

總結:

javaScript 是一門單執行緒語言,非同步操作都是放到事件迴圈佇列裡面,等待主執行棧來執行的,並沒有專門的非同步執行執行緒。

到此這篇關於js的事件迴圈機制的文章就介紹到這了,更多相關js事件迴圈內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!