瀏覽器是多進(jìn)程
? ? ? ? 瀏覽器是多進(jìn)程的,一個(gè)tab頁(yè)面一個(gè)進(jìn)程,一個(gè)進(jìn)程內(nèi)包含多個(gè)線程?!静欢€程可以看計(jì)算機(jī)原理,進(jìn)程,線程,協(xié)程,在cpu寄存器,內(nèi)存,硬盤上的操作原理就行】
? ? ? ? 瀏覽器內(nèi)核包含有多種線程,我舉例說下:
? ? ? ? GUI渲染線程,js引擎線程,http線程,事件觸發(fā)線程,定時(shí)器線程。
? ? ? ? gui渲染引擎和js引擎線程是互斥的,意思是說同時(shí)只能一個(gè)運(yùn)行。
? ? ??
JavaScript事件循環(huán)機(jī)制
? ? 瀏覽器與node的事件機(jī)制不同,瀏覽器 Event Loop 是 HTML 中定義的規(guī)范,Node Event Loop 是由 libuv 庫(kù)實(shí)現(xiàn)。
? ? 瀏覽器的事件循環(huán)機(jī)制:
? ? ? ? 執(zhí)行棧與任務(wù)隊(duì)列,
????????執(zhí)行棧是一種數(shù)據(jù)結(jié)構(gòu),先進(jìn)先出,函數(shù)被調(diào)用,會(huì)被添加到棧的頂部,執(zhí)行完后會(huì)被從棧頂移除,直到棧內(nèi)被清空。【簡(jiǎn)而言之,js里面的從上而下的運(yùn)行函數(shù),除settimeout,promise,等異步的函數(shù)】
? ? ? ? 任務(wù)隊(duì)列是由于解析器內(nèi)核決定的,由于瀏覽器需要更新dom,但只能用主線程更新,這點(diǎn)和安卓一樣,要更新界面只能主線程,原因是保證頁(yè)面渲染的一致性。因此,由setTimeout,interval,promise,async,genenrator等異步函數(shù)創(chuàng)建的事件會(huì)被推到任務(wù)隊(duì)列,直到主線程休閑的時(shí)候再來執(zhí)行,執(zhí)行完一個(gè)之后從任務(wù)隊(duì)列里面清除一個(gè),直到執(zhí)行完畢。
? ? ? ? 這里談一點(diǎn),基本所有關(guān)于頁(yè)面更新的內(nèi)核,都是只有主線程更新的。像安卓的,需要postMessage到主線程,主線程拿到信息之后才能更新,構(gòu)造會(huì)報(bào)exception。瀏覽器也是一樣。
? ??

說到任務(wù)隊(duì)列,這里我等說下,宏任務(wù)和微任務(wù) macro-mask和micro-mask
按照平時(shí)理解,狀態(tài)只分異步與同步,在js內(nèi)部,異步還可分為macro-mask和micro-mask。
macro-task包括:script(整體代碼), setTimeout, setInterval, setImmediate, I/O, UI rendering。
micro-task包括:process.nextTick, Promises, Object.observe, MutationObserver。
執(zhí)行順序:
? ? 第一次事件循環(huán)中,JavaScript 引擎會(huì)把整個(gè) script 代碼當(dāng)成一個(gè)宏任務(wù)執(zhí)行,執(zhí)行完成之后,再檢測(cè)本次循環(huán)中是否尋在微任務(wù),存在的話就依次從微任務(wù)的任務(wù)隊(duì)列中讀取執(zhí)行完所有的微任務(wù),再讀取宏任務(wù)的任務(wù)隊(duì)列中的任務(wù)執(zhí)行,再執(zhí)行所有的微任務(wù),如此循環(huán)。JS 的執(zhí)行順序就是每次事件循環(huán)中的宏任務(wù)-微任務(wù)。
? ?經(jīng)典例子:
? ??

? ? ? ??

? 參考
https://www.cnblogs.com/yqx0605xi/p/9267827.html
https://www.cnblogs.com/cangqinglang/p/8967268.html
? ??