什么是EventLoop吨娜?
理解概念之前,咱們先來兩個"栗子"吃~
栗子一:
console.log("我是")
setTimeout(function() {
console.log("姐姐")
}, 0)
console.log("超凡的")
// 輸出答案 “我是超凡的姐姐”
栗子二:
console.log("我是")
setTimeout(function() {
console.log("姐姐(天津味兒的)")
}, 0)
new Promise(()=>{
console.log("特別的")
}).then("哈哈哈")
console.log("超凡的")
//輸出答案 "我是特別的超凡的哈哈哈哈姐姐(天津味兒的)"
那各位猜對/猜錯的小伙伴淘钟,其實以上JS代碼能夠在瀏覽器中有效執(zhí)行的過程宦赠,就是瀏覽器的EventLoop
總結(jié):EvenLoop即事件循環(huán),也就是瀏覽器或Node的一種能夠javaScript單線程運行時不會阻塞的一種機制/運行機制
那么問題來了米母,為何會如何輸出勾扭?那就要說到宏任務(wù)&微任務(wù)
首先說一下宏任務(wù)和微任務(wù)的執(zhí)行內(nèi)容和范圍
宏任務(wù):主線程要執(zhí)行的代碼 & 定時器/延時器
微任務(wù):Promise的.then .catch中需要執(zhí)行的內(nèi)容
每一個宏任務(wù)都是獨立的個體,上一個宏任務(wù)執(zhí)行完铁瞒,才會考慮下一個宏任務(wù)妙色。第一個宏任務(wù)隊列里的內(nèi)容執(zhí)行完畢時,會進(jìn)行判斷看是否有微任務(wù)慧耍,如果滿足條件的微任務(wù)身辨,執(zhí)行完所有的微任務(wù)丐谋,才會執(zhí)行下一個宏任務(wù)。
EventLoop事件循環(huán)隊列
- Js是單線程的栅表,Js執(zhí)行時笋鄙,主線程遇到了異步函數(shù)不會停留,放入執(zhí)行隊列
- 滿足條件后怪瓶,將執(zhí)行隊列的內(nèi)容,放入任務(wù)隊列中排隊
- 主線程執(zhí)行完畢代碼空閑后践美,才會考慮任務(wù)隊列中的代碼
題目一:無微任務(wù)
console.log("我是小姐姐,") //宏任務(wù)1
setTimeout(function(){
console.log("你是誰洗贰?") // 宏任務(wù)2(屬于下一個宏任務(wù),定時器/延時器屬于異步內(nèi)容,放入執(zhí)行棧后陨倡,并放入任務(wù)隊列等待執(zhí)行)
})
console.log("我們認(rèn)識一下,") //宏任務(wù)1
//執(zhí)行順序 執(zhí)行宏任務(wù)1內(nèi)容完畢后敛滋,沒有滿足條件的微任務(wù),直接執(zhí)行下一個宏任務(wù)2
//輸出結(jié)果 我是小姐姐,我們認(rèn)識一下,你是誰兴革?
題目二:有微任務(wù)
說明補充1:promise的內(nèi)部既包含宏任務(wù)也包含微任務(wù)绎晃,promise內(nèi)部執(zhí)行為宏任務(wù),Promise的.then .catch中需要執(zhí)行的內(nèi)容執(zhí)行為微任務(wù)
console.log("我是") //宏任務(wù)1
setTimeout(function() {
console.log("姐姐(天津味兒的)") //宏任務(wù)2 (這里就不多說了.....)
}, 0)
new Promise(()=>{
console.log("特別的") //宏任務(wù)1 (看下方的補充1)
}).then("哈哈哈") // 滿足條件的微任務(wù)杂曲,宏任務(wù)1執(zhí)行完畢后庶艾,執(zhí)行微任務(wù),微任務(wù)執(zhí)行完畢后執(zhí)行宏任務(wù)2
console.log("超凡的") // 宏任務(wù)1
//輸出答案 "我是特別的超凡的哈哈哈哈姐姐(天津味兒的)"
題目三:什么都有
說明補充2:async表示函數(shù)是異步的的擎勘,async只有遇到了await開始咱揍,才是異步的開始。
async function fn(){
console.log('111')
}
console.log('222')
//沒有await棚饵,代碼正常輸出 111222
說明補充3:await后的內(nèi)容為宏任務(wù)煤裙,await下的內(nèi)容可以理解為.then后面的內(nèi)容,相當(dāng)于微任務(wù)
async function fn(){
console.log("111") //宏任務(wù)1
const res = await fn2()// 宏任務(wù)1 fn2() await后的內(nèi)容為宏任務(wù)
console.log(res) //微任務(wù)1 await下的內(nèi)容可以理解為.then后面的內(nèi)容噪漾,相當(dāng)于微任務(wù)
}
function fn2(){
console.log('222') //宏任務(wù)1
return 3 //宏任務(wù)1
}
fn()//宏任務(wù)1
//輸出結(jié)果為 111 222 3
小霸王來了(我們按照以上內(nèi)容自己分析)
console.log('script start')
async function async1() {
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2 end')
}
async1()
setTimeout(function() {
console.log('setTimeout')
}, 0)
new Promise(resolve => {
console.log('Promise')
resolve()
})
.then(function() {
console.log('promise1')
})
.then(function() {
console.log('promise2')
})
console.log('script end')
分析如下:
console.log('script start') //宏任務(wù)1
async function async1() {
await async2() // 宏任務(wù)1 async2() **await后的內(nèi)容為宏任務(wù)硼砰,await下的內(nèi)容為異步任務(wù)**
console.log('async1 end') //微任務(wù)1
}
async function async2() {
console.log('async2 end') //宏任務(wù)1
}
async1() // 宏任務(wù)1
setTimeout(function() {
console.log('setTimeout') //宏任務(wù)2
}, 0)
new Promise(resolve => {
console.log('Promise') //宏任務(wù)1
resolve() //宏任務(wù)1
})
.then(function() {
console.log('promise1') //微任務(wù)2
})
.then(function() {
console.log('promise2') //微任務(wù)3
})
console.log('script end') //宏任務(wù)1
輸出順序為宏任務(wù)1: script start async2 end Promise script end
微任務(wù)依次執(zhí)行:async1 end promise1 promise2
下一個宏任務(wù): setTimeout
看完題目二、題目三的兩個補充條件后欣硼,面試后大部分的宏任務(wù)和微任務(wù)練習(xí)題基本不會出錯题翰,也可以多看一些文章,加深理解分别,一起加油遍愿,歡迎互動和補充~