參考:
https://blog.csdn.net/u012925833/article/details/89306184
詳解JavaScript中的Event Loop(事件循環(huán))機(jī)制
1.為什么JS是單線(xiàn)程的鸳玩?
為了保證程序的一致性聚谁,避免多個(gè)線(xiàn)程對(duì)同一個(gè)DOM元素 既刪除又添加事件。
2.JS是如何實(shí)現(xiàn)非阻塞的呢媳谁?
執(zhí)行異步任務(wù)時(shí)灾前,不是一直等待返回結(jié)果席吴,而是會(huì)掛起這個(gè)任務(wù)婆誓,在任務(wù)返回結(jié)果后再按一定的規(guī)則去執(zhí)行相應(yīng)的回調(diào)
3.異步任務(wù)是有類(lèi)型,宏任務(wù)和微任務(wù)羹饰。遇到異步任務(wù)后伊滋,會(huì)將其分別放到宏任務(wù)隊(duì)列和微任務(wù)隊(duì)列中。在當(dāng)前執(zhí)行棧中的同步代碼運(yùn)行完之后队秩,先執(zhí)行微任務(wù)隊(duì)列中的任務(wù)笑旺,再執(zhí)行宏任務(wù)隊(duì)列。在執(zhí)行微任務(wù)隊(duì)列中的任務(wù)時(shí)馍资,如果又遇到微任務(wù)燥撞,會(huì)放到微任務(wù)隊(duì)列中的隊(duì)尾,遇到宏任務(wù)時(shí)迷帜,就放到宏任務(wù)隊(duì)列中的隊(duì)尾。
如果在宏任務(wù)隊(duì)列里又遇到微任務(wù)色洞,說(shuō)是在執(zhí)行完當(dāng)前宏任務(wù)之后戏锹,會(huì)檢查微任務(wù)隊(duì)列執(zhí)行微任務(wù),微任務(wù)隊(duì)列清空之后火诸,再重新執(zhí)行剩下的宏任務(wù)隊(duì)列锦针。
后續(xù)的宏任務(wù)和該微任務(wù)的執(zhí)行順序不定,有時(shí)宏任務(wù)先執(zhí)行置蜀,有時(shí)微任務(wù)先執(zhí)行奈搜。
setTimeout 、setTimeout 是宏任務(wù)
Promise 盯荤、 async await馋吗、MutaionObserver 是微任務(wù)
- 為什么要了解事件循環(huán)的執(zhí)行順序?
合理的使用各種延遲事件的方法秋秤,有助于代碼更好的按照其優(yōu)先級(jí)去執(zhí)行宏粤。
5.當(dāng)前執(zhí)行棧——微任務(wù)隊(duì)列——宏任務(wù)隊(duì)列 灼卢。執(zhí)行隊(duì)列里的任務(wù)時(shí)绍哎,是在當(dāng)前執(zhí)行棧中執(zhí)行的,執(zhí)行之后又一次檢查兩個(gè)隊(duì)列鞋真。
6.當(dāng)前執(zhí)行棧執(zhí)行完畢時(shí)會(huì)立刻先處理所有微任務(wù)隊(duì)列中的事件崇堰,然后再去宏任務(wù)隊(duì)列中取出一個(gè)事件。同一次事件循環(huán)中,微任務(wù)永遠(yuǎn)在宏任務(wù)之前執(zhí)行海诲。
有多次事件循環(huán)嗎繁莹?以什么判斷本次事件循環(huán)結(jié)束下一次事件循環(huán)開(kāi)始了呢?
7.為什么有些瀏覽器會(huì)在執(zhí)行順序上有不同的表現(xiàn)呢饿肺?
其實(shí)是因?yàn)椤皩romise作為task還是microtask引起的”蒋困,不同瀏覽器的解析不一樣
下面代碼的打印順序是如何的?
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('script end');
//正確答案是: script start, script end, promise1, promise2, setTimeout,
//a 的初始值為true和false時(shí)敬辣,執(zhí)行結(jié)果分別是什么
var a = false;
setTimeout(function(){
a = !a;
console.log(a)
}, 100)
while(a){
console.log('while執(zhí)行了')
}