例項理解promise、macro-task、micro-task
阿新 • • 發佈:2018-11-07
setTimeout(function(){
console.log(1);
}, 0);
new Promise(function executor(resolve){
console.log(2);
for(var i=0; i<10000; i++){
i == 999 && resolve();
}
console.log(3);
}).then(function(){
console.log(4);
});
console.log(5);
先看結果:
js中事件執行主要分為兩種任務型別:macro-task(task)(巨集任務)、micro-task(Job queue)(微任務);
什麼會加入到task,什麼會加入到micro-task?
task:script(全域性任務),setTimeout,setInterval,setImmediate ,I/O,UI渲染等 ;
micro-task: promise,Object,observe,process.nextTick,MutationObserver等;(通俗來說是執行定時器、事件、ajax事件等操作時);
那麼執行順序是什麼樣的:
script先進入函式呼叫棧,繼續執行
–>遇到巨集任務時把巨集任務加入巨集任務執行佇列(但暫不執行),遇到微任務把微任務加入微任務執行佇列(但暫不執行),等到函式呼叫棧所有內容出棧後
–>去執行微任務佇列
–>然後再回頭執行巨集任務佇列
–>再進入函式呼叫棧,執行微任務佇列,再執行巨集任務佇列,直到巨集任務佇列執行完畢
注意:
1、undefined是console.log(5);列印時輸出的(因為控制檯執行程式碼,會返回最後一句程式碼的返回值,即consol.log()的返回值,即undefined)
2、每一個事件迴圈(event loop)都有一個microtasks
3、new的物件立即執行,promise建構函式傳入的函式會在本次new 操作立刻執行
4、.then和setTimeout都是非同步操作,但優先順序不一樣,then()優先順序更高些,所以4比1先輸出
綜合以上,上述程式碼執行過程如下:
// 加入巨集任務佇列,第五輸出1 setTimeout(function(){ console.log(1); }, 0); // new立即執行而且是promise(加入微任務佇列) new Promise(function executor(resolve){ // 第一,輸出2 console.log(2); for(var i=0; i<10000; i++){ i == 999 && resolve(); } //第二, 輸出3 console.log(3); }).then(function(){ // promise中的then操作是放在執行棧,也就是主執行緒的最後,暫存,繼續往下走 // 第四,輸出4 console.log(4); }); // 第三,輸出5 console.log(5);