事件輪詢概念
? 事件輪詢(Event Loop)是一個很重要的概念拢肆,指的是計算機系統(tǒng)的一種運行機制减响。JavaScript語言就是采用的這種機制靖诗,來解決單線程運行帶來的一些問題。
想要理解EventLoop支示,就要從程序的運行模式講起刊橘。運行以后的程序叫做"進程"(process),一般情況下颂鸿,一個進程一次只能執(zhí)行一個任務促绵。
如果有很多任務需要執(zhí)行,不外乎三種解決方法嘴纺。
(1)排隊败晴。因為一個進程一次只能執(zhí)行一個任務,只好等前面的任務執(zhí)行完了栽渴,再執(zhí)行后面的任務尖坤。
(2)新建進程。使用fork命令闲擦,為每個任務新建一個進程慢味。
(3)新建線程。因為進程太耗費資源墅冷,所以如今的程序往往允許一個進程包含多個線程纯路,由線程去完成任務。
?以JavaScript語言為例寞忿,它是一種單線程語言驰唬,所有任務都在一個線程下完成,即采用上面的第一種方法腔彰,一旦遇到大量任務或者遇到一個耗時的任務叫编,網(wǎng)頁就會出現(xiàn)假死的狀態(tài),因為JavaScript停不下來萍桌,也就無法響應用戶的行為宵溅。
很多人問為什么JavaScript不能實現(xiàn)多線程呢,例如如果是多線程的話上炎,多個線程去操作同一個Dom元素恃逻,那么結(jié)果就造成一個很嚴重的問題,所以js是單線程的藕施,但如果完全由上至下的執(zhí)行代碼寇损,前面的代碼沒有執(zhí)行完,后面必須要等待當前執(zhí)行完畢裳食,這樣的效率是非常低的矛市,所以有了異步的概念,JavaScript 的主線程是單線程的诲祸,但是也有其他的線程去幫我們實現(xiàn)異步操作浊吏,比如Ajax 線程而昨、定時器線程、事件線程找田。
JavaScript的任務
1.宏任務
宏任務包括整體代碼script歌憨,setTimeout,setInterval墩衙, I/O务嫡,UI Rendering
2.微任務
微任務包括Promise.then(非new Promise),process.nextTick
不同類型的任務會進入不同的Event Queue漆改,有宏任務的隊列和微任務的隊列心铃。
我們來看下面這道題就可以清晰了解宏、微任務區(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í)行流程:
通過圖片我們可以看出去扣,進入整體代碼(宏任務)后,開始第一次循環(huán)樊破。接著執(zhí)行所有的微任務厅篓。然后再次從宏任務開始,找到其中一個任務隊列執(zhí)行完畢捶码,再執(zhí)行所有的微任務
所以上面那道題是宏任務會先將延時器放到事件隊列中,等待下一輪執(zhí)行宏任務才會執(zhí)行延時器或链,繼續(xù)找宏任務a b c 惫恼,直到?jīng)]有宏任務就會執(zhí)行微任務,也就是e 澳盐,微任務也執(zhí)行完畢祈纯,就會開啟新一輪的執(zhí)行宏任務,所以最后打印d