在javascript中,微任務包含:1、「Promise」;2、「Object.observe」;3、「MutationObserver」;4、Node.js環境下的「process.nextTick」;5、「async/await」。
本教學操作環境:windows7系統、javascript1.8.5版、Dell G3電腦。
事件迴圈
JavaScript 語言的一大特點就是單執行緒,也就是說,同一個時間只能做一件事。為了協調事件、使用者互動、指令碼、UI 渲染和網路處理等行為,防止主執行緒的不阻塞,Event Loop 的方案應用而生。Event Loop 包含兩類:一類是基於 Browsing Context,一種是基於 Worker。二者的執行是獨立的,也就是說,每一個 JavaScript 執行的"執行緒環境"都有一個獨立的 Event Loop,每一個 Web Worker 也有一個獨立的 Event Loop。
本文所涉及到的事件迴圈是基於 Browsing Context。
任務佇列
根據規範,事件迴圈是通過任務佇列的機制來進行協調的。一個 Event Loop 中,可以有一個或者多個任務佇列(task queue),一個任務佇列便是一系列有序任務(task)的集合;每個任務都有一個任務源(task source),源自同一個任務源的 task 必須放到同一個任務佇列,從不同源來的則被新增到不同佇列。setTimeout/Promise 等API便是任務源,而進入任務佇列的是他們指定的具體執行任務。
在事件迴圈中,每進行一次迴圈操作稱為 tick,每一次 tick 的任務處理模型是比較複雜的,但關鍵步驟如下:
在此次 tick 中選擇最先進入佇列的任務(oldest task),如果有則執行(一次)
檢查是否存在 Microtasks,如果存在則不停地執行,直至清空 Microtasks Queue
更新 render
主執行緒重複執行上述步驟
在上訴tick的基礎上需要了解幾點:
JS分為同步任務和非同步任務
同步任務都在主執行緒上執行,形成一個執行棧
主執行緒之外,事件觸發執行緒管理著一個任務佇列,只要非同步任務有了執行結果,就在任務佇列之中放置一個事件。
一旦執行棧中的所有同步任務執行完畢(此時JS引擎空閒),系統就會讀取任務佇列,將可執行的非同步任務新增到可執行棧中,開始執行。
宏任務
(macro)task,可以理解是每次執行棧執行的程式碼就是一個宏任務(包括每次從事件佇列中獲取一個事件回撥並放到執行棧中執行)。
瀏覽器為了能夠使得JS內部(macro)task與DOM任務能夠有序的執行,會在一個(macro)task執行結束後,在下一個(macro)task 執行開始前,對頁面進行重新渲染,流程如下:
(macro)task->渲染->(macro)task->...
宏任務包含:
script(整體程式碼) setTimeout setInterval I/O UI互動事件 postMessage MessageChannel setImmediate(Node.js 環境)
微任務
microtask,可以理解是在當前 task 執行結束後立即執行的任務。也就是說,在當前task任務後,下一個task之前,在渲染之前。
所以它的響應速度相比setTimeout(setTimeout是task)會更快,因為無需等渲染。也就是說,在某一個macrotask執行完後,就會將在它執行期間產生的所有microtask都執行完畢(在渲染前)。
微任務包含:
Promise Object.observe MutationObserver process.nextTick(Node.js 環境) async/await
執行機制
在事件迴圈中,每進行一次迴圈操作稱為 tick,每一次 tick 的任務處理模型是比較複雜的,但關鍵步驟如下:
執行一個宏任務(棧中沒有就從事件佇列中獲取)
執行過程中如果遇到微任務,就將它新增到微任務的任務佇列中
宏任務執行完畢後,立即執行當前微任務佇列中的所有微任務(依次執行)
當前宏任務執行完畢,開始檢查渲染,然後GUI執行緒接管渲染
渲染完畢後,JS執行緒繼續接管,開始下一個宏任務(從事件佇列中獲取)
如圖:
【相關推薦:】
以上就是javascript中微任務包含哪些的詳細內容,更多請關注TW511.COM其它相關文章!