JS 主線程不斷的循環往復的從任務隊列中讀取任務,執行任務,這種運行機制稱為事件循環(event loop)推薦看一個2分鐘了解event loop
宏任務和微任務
瀏覽器的事件循環(event loop)中分成宏任務和微任務。JS 中任務分成同步任務和異步任務。
- 宏任務(macro task)
JS 中主棧執行的大多數的任務,例如:定時器,事件綁定,ajax,回調函數,node中fs操作模塊等就是宏任務
- 微任務(micro task)
promise, async/await, process.nextTick等就是微任務。
為什么要引入微任務,只有宏任務可以嗎?
微任務的引入是為了解決異步回調的問題,假設只有宏任務,那么每一個宏任務執行完后回調函數也放入宏任務隊列,這樣會造成隊列多長,回調的時間變長,這樣會造成頁面的卡頓,所以引入了微任務。
- 宏任務和微任務的執行順序(很重要)
- 主棧隊列就是一個宏任務,每一個宏任務執行完就會執行宏任務中的微任務,直到微任務全部都執行完,才開始執行下一個宏任務。
- js 中任務的執行順序優先級是:主棧全局任務(宏任務) > 宏任務中的微任務 > 下一個宏任務。,所以 promise(微任務) 的執行順序優先級高于setTimeout定時器。
- 不能滿目的將 .then 的回調放入微任務隊列;因為沒有調用 resolve或者reject 之前是不算異步任務完成的, 所以不能將回調隨意的放入微任務事件隊列
- await 是一個讓出線程的標志。await 后面的表達式會先執行一遍,將 await 后面的代碼加入到 micro task中這個微任務是 promise 隊列中微任務,然后就會跳出整個 async 函數來繼續執行后面的代碼。
- process.nextTick 是一個獨立于 eventLoop 的任務隊列,主棧中的宏任務每一次結束后都是先執行 process.nextTick隊列,在執行微任務 promise 的 .then()。
- 每一個宏任務和宏任務的微任務執行完后都會對頁面 UI 進行渲染。