js 單線程、宏任務與微任務的執行順序

js 單線程、宏任務與微任務的執行順序

js 單線程

衆所周知js是單線程,但js是可以執行同步和異步任務的,同步的任務衆人皆知是按照順序去執行的;

而異步任務的執行,是有一個優先級的順序的,包括了 **宏任務(macrotasks)**和 微任務(microtasks)

宏任務

是指消息隊列中的等待被主線程執行的事件,宏任務執行時都會重新創建棧,然後調用宏任務中的函數,棧也會隨着變化,但宏任務執行結束時,棧也會隨之銷燬。

包括 整體代碼script,setTimeout,setInterval ,setImmediate,I/O,UI renderingnew ,Promise*

微任務

可以把微任務看成是一個需要異步執行的函數,****執行時機是在主函數執行結束之後、當前宏任務結束之前****

包括 Promises.(then catch finally),process.nextTick, MutationObserver

微任務是基於消息隊列、事件循環、UI 主線程還有堆棧而來的

區別

宏任務和微任務的區別在於在事件循環機制中,執行的機制不同

每次執行完所有的同步任務後,會在任務隊列中取出異步任務,先將所有微任務執行完成後,纔會執行宏任務
所以可以得出結論, 微任務會在宏任務之前執行。
我們在工作常用到的宏任務是 setTimeout,而微任務是 Promise.then

注意這裏是Promise.then,也就是說 new Promise在實例化的過程中所執行的代碼是同步的,而在 then中註冊的回調函數纔是異步。

setTimeout(function(){
    console.log('1')
});
new Promise(function(resolve){
    console.log('2');
    resolve();
}).then(function(){
    console.log('3')
});
console.log('4');
new Promise(function(resolve){
    console.log('5');
    resolve();
}).then(function(){
    console.log('6')
});
setTimeout(function(){
    console.log('7')
});
function bar(){
    console.log('8')
    foo()
}
function foo(){
    console.log('9')
}
console.log('10')
bar()

 

解析:
首先瀏覽器執行Js代碼由上至下順序,遇到setTimeout,把setTimeout分發到宏任務Event Queue中
new Promise屬於主線程任務直接執行打印2
Promis下的then方法屬於微任務,把then分到微任務 Event Queue中
console.log(‘4’)屬於主線程任務,直接執行打印4
又遇到new Promise也是直接執行打印5,Promise 下到then分發到微任務Event Queue中
又遇到setTimouse也是直接分發到宏任務Event Queue中,等待執行
console.log(‘10’)屬於主線程任務直接執行
遇到bar()函數調用,執行構造函數內到代碼,打印8,在bar函數中調用foo函數,執行foo函數到中代碼,打印9
主線程中任務執行完後,就要執行分發到微任務Event Queue中代碼,實行先進先出,所以依次打印3,6
微任務Event Queue中代碼執行完,就執行宏任務Event Queue中代碼,也是先進先出,依次打印1,7。
最終結果:2,4,5,10,8,9,3,6,1,7

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章