b.淺談js的事件輪詢(宏任務(wù)、微任務(wù))

事件輪詢概念


? 事件輪詢(Event Loop)是一個很重要的概念,指的是計算機系統(tǒng)的一種運行機制。JavaScript語言就是采用的這種機制,來解決單線程運行帶來的一些問題。

想要理解EventLoop,就要從程序的運行模式講起。運行以后的程序叫做"進程"(process),一般情況下,一個進程一次只能執(zhí)行一個任務(wù)。

如果有很多任務(wù)需要執(zhí)行,不外乎三種解決方法。

(1)排隊。因為一個進程一次只能執(zhí)行一個任務(wù),只好等前面的任務(wù)執(zhí)行完了,再執(zhí)行后面的任務(wù)。

(2)新建進程。使用fork命令,為每個任務(wù)新建一個進程。

(3)新建線程。因為進程太耗費資源,所以如今的程序往往允許一個進程包含多個線程,由線程去完成任務(wù)。

?以JavaScript語言為例,它是一種單線程語言,所有任務(wù)都在一個線程下完成,即采用上面的第一種方法,一旦遇到大量任務(wù)或者遇到一個耗時的任務(wù),網(wǎng)頁就會出現(xiàn)假死的狀態(tài),因為JavaScript停不下來,也就無法響應(yīng)用戶的行為。

很多人問為什么JavaScript不能實現(xiàn)多線程呢,例如如果是多線程的話,多個線程去操作同一個Dom元素,那么結(jié)果就造成一個很嚴重的問題,所以js是單線程的,但如果完全由上至下的執(zhí)行代碼,前面的代碼沒有執(zhí)行完,后面必須要等待當前執(zhí)行完畢,這樣的效率是非常低的,所以有了異步的概念,JavaScript 的主線程是單線程的,但是也有其他的線程去幫我們實現(xiàn)異步操作,比如Ajax 線程、定時器線程、事件線程。


JavaScript的任務(wù)


1.宏任務(wù)

宏任務(wù)包括整體代碼script,setTimeout,setInterval, I/O,UI Rendering

2.微任務(wù)

微任務(wù)包括Promise.then(非new Promise),process.nextTick

不同類型的任務(wù)會進入不同的Event Queue,有宏任務(wù)的隊列和微任務(wù)的隊列。

我們來看下面這道題就可以清晰了解宏、微任務(wù)區(qū)別:

setTimeout(() => { console.log( 'd' ); }, 0);

new Promise(resolve=>{

console.log('a');?

for(let i =0;i<10000;i++){ i == 9999 && resolve(); } console.log( 'b' ) }).then(()=>{ console.log( 'e' ) })??

?console.log( 'c' )?

答案是 a b c e d,讓我們來看看執(zhí)行流程:

圖1

通過圖片我們可以看出,進入整體代碼(宏任務(wù))后,開始第一次循環(huán)。接著執(zhí)行所有的微任務(wù)。然后再次從宏任務(wù)開始,找到其中一個任務(wù)隊列執(zhí)行完畢,再執(zhí)行所有的微任務(wù)

所以上面那道題是宏任務(wù)會先將延時器放到事件隊列中,等待下一輪執(zhí)行宏任務(wù)才會執(zhí)行延時器,繼續(xù)找宏任務(wù)a b c ,直到?jīng)]有宏任務(wù)就會執(zhí)行微任務(wù),也就是e ,微任務(wù)也執(zhí)行完畢,就會開啟新一輪的執(zhí)行宏任務(wù),所以最后打印d

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容