event_loop中不一樣異步操做的執行順序

關於js的單線程、怎麼建立一個異步任務都是老生常談的話題了,咱們今天就總結一下js不一樣的異步操做到底執行順序如何。node

首先咱們要明白js兩種任務類型,一個是macrotask(宏任務),一個是 microtask(微任務)。一個宏任務就是一個事件循環,一個宏任務執行完畢後js就會執行下一個宏任務,而微任務就是在兩個宏任務執行中間執行。
咱們先給js中異步常見的異步操做來根據不一樣任務類型進行分類ajax

宏任務promise

  • script(同步代碼)
  • setTimeout
  • setInterval
  • setImmediate
  • I/O(ajax請求)異步

微任務函數

  • promise

    node中的process.nextTick是將任務放到當前宏任務的隊尾執行,比較特殊,也算是一個特殊的微任務。oop

console.log(1);
setTimeout(()=>console.log(2), 1)
setTimeout(()=> console.log(3), 0)
Promise.resolve().then(()=> console.log(4));
setImmediate(()=> console.log(5))
process.nextTick(()=> console.log(6))
console.log(7);

因此咱們能夠來測試下上面這段代碼的執行順序,首先確定輸出的是 1 7 由於他們兩個是屬於第一個宏任務中的代碼,接下來是 6 當前宏任務結束後process.nextTick 執行。而在下一個宏任務執行以前,微任務promise會指向,因此下來是 4。同時咱們要知道setTimeout的時間最小值是1因此 1 和 0 實際上是同樣的,2必定會在3以前執行。可是setImmediate和setTimeout(, 0)執行順序其實不肯定的,當咱們將這段代碼直接在node中執行,輸出的是1764235,也就是說setImmediate後執行。可是咱們將這段代碼放到一個setTimeout中執行,輸出的是1764523。測試

咱們知道 setTimeout 的回調函數在 timer 階段執行,setImmediate 的回調函數在 check 階段執行,event loop 的開始會先檢查 timer 階段,可是在開始以前到 timer 階段會消耗必定時間,因此就會出現兩種狀況:

timer 前的準備時間超過 1ms,知足 loop->time >= 1,則執行 timer 階段(setTimeout)的回調函數
timer 前的準備時間小於 1ms,則先執行 check 階段(setImmediate)的回調函數,下一次 event loop 執行 timer 階段(setTimeout)的回調函數

這是對網上對這個現象的解釋。線程

相關文章
相關標籤/搜索