第一道題:
setTimeout(()=>{
console.log('A');
},0);
var obj={
func:function () {
setTimeout(function () {
console.log('B')
},0);
return new Promise(function (resolve) {
console.log('C');
resolve();
})
}
};
obj.func().then(function () {
console.log('D')
});
console.log('E');
解析:
js任務(wù)隊列有兩種分预,宏任務(wù)隊列,微任務(wù)隊列噩峦。js的事件循環(huán)調(diào)度的就是宏任務(wù)隊列锭沟。一個宏任務(wù)執(zhí)行完畢后會去檢查微任務(wù)隊列,如果微任務(wù)隊列有任務(wù)识补,則按序執(zhí)行之冈钦,至微任務(wù)隊列為空,然后去宏任務(wù)隊列執(zhí)行下一個宏任務(wù)李请,就這么簡單瞧筛。
看上面的題,當(dāng)前正在執(zhí)行的腳本也是一個宏任務(wù)导盅。首先较幌,當(dāng)前腳本推入執(zhí)行棧執(zhí)行,先碰到的是一個定時器setTimeout白翻,它會創(chuàng)建一個宏任務(wù)放到宏任務(wù)隊列(暫記為setTimeoutA)并且執(zhí)行的時候會打印一個A乍炉,接下來是一個對象聲明绢片,然后是調(diào)用對象的func方法,此時func方法被推入執(zhí)行棧岛琼。func方法首先創(chuàng)建了一個定時器底循,所以宏任務(wù)隊列又會增加一個宏任務(wù)(暫記為setTimeoutB),該定時器會輸出一個B槐瑞。接下來方法創(chuàng)建一個Promise并返回熙涤,我們知道Promise創(chuàng)建的時候會立即執(zhí)行,所以這個時候控制臺就出現(xiàn)了第一個打印出來的值C困檩,該Promise有一個回調(diào)祠挫,該回調(diào)會被當(dāng)成是微任務(wù)添加到微任務(wù)隊列(暫記為PromiseD),并且該回調(diào)執(zhí)行時會在控制臺打印出D悼沿。接下來func執(zhí)行完了等舔,方法退棧,然后繼續(xù)往下執(zhí)行糟趾,接下來的代碼很簡單慌植,直接在控制臺打印輸出了一個E。此時控制臺已經(jīng)輸出了C义郑、E
上面的這個腳本作為一個宏任務(wù)執(zhí)行完了之后該去檢查微任務(wù)隊列蝶柿。根據(jù)上面的分析,我們先看下當(dāng)前宏任務(wù)隊列和微任務(wù)隊列都有哪些任務(wù)魔慷。
宏任務(wù)隊列:setTimeoutA,setTimeoutB
微任務(wù):PromiseD
因為一個宏任務(wù)執(zhí)行完畢后會去檢查微任務(wù)隊列著恩,并執(zhí)行隊列里的微任務(wù)院尔。此時微任務(wù)隊列中有PromiseD,所以執(zhí)行該微任務(wù)喉誊,并在控制臺打印出D邀摆。然后,微任務(wù)隊列空了伍茄,所以繼續(xù)去執(zhí)行宏任務(wù)隊列中的任務(wù)栋盹。所以,接下來就是setTImeoutA敷矫,控制臺輸出A例获。然后去檢查微任務(wù)隊列,此時微任務(wù)隊列為空曹仗。繼續(xù)宏任務(wù)隊列的任務(wù)榨汤。setTimeoutB任務(wù)被執(zhí)行,控制臺輸出B怎茫。此時收壕,所有隊列任務(wù)就都執(zhí)行完了妓灌。
此時,控制臺輸出的字符串按順序就是是:C蜜宪,E虫埂,D,A圃验,B
第二道題:
async function async1 () {
console.log('2 async1 start');
await async2(); // await 后面的代碼相當(dāng)于then()的回調(diào)函數(shù)
console.log('6 async1 end')
}
async function async2 () {
console.log('3 async2')
}
console.log('1 script start');
setTimeout(function () {
console.log('8 setTimeout')
}, 0);
async1();
new Promise(function (resolve) {
console.log('4 promise1');
resolve()
}).then(function () {
console.log('7 promise2')
});
console.log('5 script end')
執(zhí)行的結(jié)果:
async
async 函數(shù)默認返回一個promise對象
如果async函數(shù)中的代碼正常執(zhí)行,則會調(diào)用Promise.resolve()包裝返回的內(nèi)容
如果函數(shù)內(nèi)的代碼報錯,則調(diào)用Promise.reject()拋出錯誤
async function async2(){
const a = 'a'
console.log(a)
return a;
}
async2()
// Promise {<fulfilled>: "a"}
宏任務(wù):
script
setTimeout
setInterval
setImmediate
I/O
UI rendering
微任務(wù):
- process.nextTick(node 獨有)
- promise
- MutationObserver