先上代碼
console.log(1)
// setTimeout1
setTimeout(function () {
new Promise(function (resolve) {
console.log('promise in setTimeout1')
resolve()
}).then(function () {
console.log('then in setTimeout1')
})
}, 10)
new Promise(function (resolve) {
console.log(3)
for (var i = 100000; i > 0; i--) {
i == 1 && resolve()
}
console.log(4)
}).then(function () {
console.log(5)
})
// setTimeout2
setTimeout(function () {
console.log('setTimeout2')
}, 10)
console.log(7)
執(zhí)行順序
- 首先 js 整塊代碼為宏任務(wù)华临,放入宏任務(wù)隊列,為第一個宏任務(wù)端考,所以先執(zhí)行第一個雅潭,結(jié)果先輸出 1
- 遇到第一個 setimeout 放入定時器線程,等定時器執(zhí)行完跛梗,將回調(diào)放入 宏任務(wù)隊列中寻馏,10ms 后放入宏任務(wù)隊列,此時回調(diào)隊列中有
[js整塊代碼為一次宏任務(wù),setimout1的回調(diào)]
- 繼續(xù)執(zhí)行,看到 promise.then 為微任務(wù)核偿,所以先將 newpromis 中的同步操作先輸出 3诚欠、4,然后將.then 回調(diào)放入 微任務(wù)隊列中,所以現(xiàn)在微任務(wù)隊列有
[.then]
- 繼續(xù)向下執(zhí)行 看到 setimout 為宏任務(wù)轰绵,所以先放入宏任務(wù)隊列中去不管他,所以當(dāng)前宏任務(wù)隊列中有
[js整塊代碼為一次宏任務(wù),setimout1的回調(diào),setimout2的回調(diào)]
- 執(zhí)行輸出 7 ,到此 第一次宏任務(wù)也就是 js 整體代碼塊執(zhí)行完了粉寞,然后看看 有沒有待執(zhí)行的微任務(wù),現(xiàn)在微任務(wù)隊列中有
[.then]
所以輸出 5 ,然后沒有微任務(wù)了
以上 js 第一次宏任務(wù)執(zhí)行完畢左腔,輸出結(jié)果為,1-3-4-7-5 接下來唧垦,看看宏任務(wù)隊列是否有其他的宏任務(wù),我們看到第四點中 宏任務(wù)隊列有[js整塊代碼為一次宏任務(wù),setimout1的回調(diào),setimout2的回調(diào)]
,那接下來執(zhí)行第二個宏任務(wù),也就是 setimout1 的回調(diào)
- setimout1 回調(diào)部分液样,可以看到順序執(zhí)行振亮,有一個輸出
console.log('promise in setTimeout1')
;,然后有個.then 的回調(diào)函數(shù)輸出 console.log('then in setTimeout1')
;根據(jù)機制鞭莽,肯定先執(zhí)行宏任務(wù)后執(zhí)行.then 微任務(wù)坊秸,到此執(zhí)行結(jié)果為:1-3-4-7-5-promise in setTimeout1-then in setTimeout1
- ,接下來看到當(dāng)前宏任務(wù)中沒有其他微任務(wù)了,所以接著執(zhí)行宏任務(wù)隊列中第三個宏任務(wù)澎怒,也就是 setimout2 的回調(diào)
所以最后的結(jié)果為1->3->4->7->5->promise in setTimeout1->then in setTimeout1->setTimeout2
總結(jié):
- 宏任務(wù)有宏任務(wù)隊列
- 微任務(wù)有微任務(wù)隊列
- js 一次只能執(zhí)行一個宏任務(wù)
- 執(zhí)行完第一個宏任務(wù)褒搔,準備執(zhí)行第二個宏任務(wù)的時候要看看微任務(wù)隊列中有沒有可執(zhí)行的微任務(wù),如果有喷面,優(yōu)先將微任務(wù)執(zhí)行完成
以上的過程不斷地重復(fù)就形成了 EVENT-LOOP