摘要:事件循環(huán)機(jī)制首先區(qū)分進(jìn)程和線程進(jìn)程是資源分配的最小單位系統(tǒng)會(huì)給它分配內(nèi)存不同的進(jìn)程之間是可以同學(xué)的,如管道命名管道消息隊(duì)列一個(gè)進(jìn)程里有單個(gè)或多個(gè)線程瀏覽器是多進(jìn)程的,因?yàn)橄到y(tǒng)給它的進(jìn)程分配了資源內(nèi)存打開會(huì)有一個(gè)主進(jìn)程,每打開一個(gè)頁就有一個(gè)獨(dú)
JS JavaScript事件循環(huán)機(jī)制 首先區(qū)分進(jìn)程和線程
進(jìn)程是cpu資源分配的最小單位(系統(tǒng)會(huì)給它分配內(nèi)存)
不同的進(jìn)程之間是可以同學(xué)的,如管道、FIFO(命名管道)、消息隊(duì)列
一個(gè)進(jìn)程里有單個(gè)或多個(gè)線程
瀏覽器是多進(jìn)程的,因?yàn)橄到y(tǒng)給它的進(jìn)程分配了資源(cpu、內(nèi)存)(打開Chrome會(huì)有一個(gè)主進(jìn)程,每打開一個(gè)Tab頁就有一個(gè)獨(dú)立的進(jìn)程)
GUI渲染線程
JS引擎線程
事件觸發(fā)線程
定時(shí)觸發(fā)器線程
異步HTTP請(qǐng)求線程
事件循環(huán)機(jī)制上圖解釋:
同步和異步任務(wù)分別進(jìn)入不同的執(zhí)行"場(chǎng)所",同步的進(jìn)入主線程,異步的進(jìn)入Event Table并注冊(cè)函數(shù)
當(dāng)指定的事情完成時(shí),Event Table會(huì)將這個(gè)函數(shù)移入Event Queue
當(dāng)棧中的代碼執(zhí)行完畢,執(zhí)行棧(call stack)中的任務(wù)為空時(shí),就會(huì)讀取任務(wù)隊(duì)列(Event quene)中的事件,去執(zhí)行對(duì)應(yīng)的回調(diào)
如此循環(huán),形成js的事件循環(huán)機(jī)制(Event Loop)
先看一段代碼的執(zhí)行結(jié)果:
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");
執(zhí)行結(jié)果: script start , script end , promise1 , promise2 , setTimeout
JS中分為兩種任務(wù)類型:macrotask和microtask,在ECMAScript中,microtask稱為jobs,macrotask可稱為task
macrotask(又稱之為宏任務(wù)),可以理解是每次執(zhí)行棧執(zhí)行的代碼就是一個(gè)宏任務(wù)(包括每次從事件隊(duì)列中獲取一個(gè)事件回調(diào)并放到執(zhí)行棧中執(zhí)行)
每一個(gè)task會(huì)從頭到尾將這個(gè)任務(wù)執(zhí)行完畢,不會(huì)執(zhí)行其它
瀏覽器為了能夠使得JS內(nèi)部task與DOM任務(wù)能夠有序的執(zhí)行,會(huì)在一個(gè)task執(zhí)行結(jié)束后,在下一個(gè) task 執(zhí)行開始前,對(duì)頁面進(jìn)行重新渲染 (task->渲染->task->...)
microtask(又稱為微任務(wù)),可以理解是在當(dāng)前 task 執(zhí)行結(jié)束后立即執(zhí)行的任務(wù)
也就是說,在當(dāng)前task任務(wù)后,下一個(gè)task之前,在渲染之前
所以它的響應(yīng)速度相比setTimeout(setTimeout是task)會(huì)更快,因?yàn)闊o需等渲染
也就是說,在某一個(gè)macrotask執(zhí)行完后,就會(huì)將在它執(zhí)行期間產(chǎn)生的所有microtask都執(zhí)行完畢(在渲染前)
macrotask:主代碼塊,setTimeout,setInterval等(可以看到,事件隊(duì)列中的每一個(gè)事件都是一個(gè)macrotask)
microtask:Promise,process.nextTick等
補(bǔ)充:在node環(huán)境下,process.nextTick的優(yōu)先級(jí)高于Promise,也就是可以簡單理解為:在宏任務(wù)結(jié)束后會(huì)先執(zhí)行微任務(wù)隊(duì)列中的nextTickQueue部分,然后才會(huì)執(zhí)行微任務(wù)中的Promise部分。
執(zhí)行一個(gè)宏任務(wù)(棧中沒有就從事件隊(duì)列中獲?。?/p>
執(zhí)行過程中如果遇到微任務(wù),就將它添加到微任務(wù)的任務(wù)隊(duì)列中
宏任務(wù)執(zhí)行完畢后,立即執(zhí)行當(dāng)前微任務(wù)隊(duì)列中的所有微任務(wù)(依次執(zhí)行)
當(dāng)前宏任務(wù)執(zhí)行完畢,開始檢查渲染,然后GUI線程接管渲染
渲染完畢后,JS線程繼續(xù)接管,開始下一個(gè)宏任務(wù)(從事件隊(duì)列中獲?。?/p>
如圖:
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/101187.html
摘要:主線程不斷重復(fù)上面的三步,此過程也就是常說的事件循環(huán)。所以主線程代碼執(zhí)行時(shí)間過長,會(huì)阻塞事件循環(huán)的執(zhí)行。參考資料這一次,徹底弄懂執(zhí)行機(jī)制任務(wù)隊(duì)列的順序機(jī)制事件循環(huán)搞懂異步事件輪詢與中的事件循環(huán) 1. 說明 讀過本文章后,您能知道: JavaScript代碼在瀏覽器中的執(zhí)行機(jī)制和事件循環(huán) 面試中經(jīng)常遇到的代碼輸出順序問題 首先通過一段代碼來驗(yàn)證你是否了解代碼輸出順序,如果你不知道輸出...
摘要:異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)異步任務(wù)從任務(wù)隊(duì)列回到執(zhí)行棧,回調(diào)函數(shù)就會(huì)執(zhí)行。事件循環(huán)主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱為。事件循環(huán)事件循環(huán)是指主線程重復(fù)從消息隊(duì)列中取消息執(zhí)行的過程。 參考鏈接:這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制https://zhuanlan.zhihu.com/p/...從瀏覽器多進(jìn)程到JS單線程,JS運(yùn)行機(jī)制...
摘要:事件循環(huán)機(jī)制事件循環(huán)機(jī)制分為瀏覽器和事件循環(huán)機(jī)制,兩者的實(shí)現(xiàn)技術(shù)不一樣,瀏覽器是中定義的規(guī)范,是由庫實(shí)現(xiàn)。整個(gè)事件循環(huán)完成之后,會(huì)去檢測(cè)微任務(wù)的任務(wù)隊(duì)列中是否存在任務(wù),存在就執(zhí)行。 文章來自我的 github 博客,包括技術(shù)輸出和學(xué)習(xí)筆記,歡迎star。 先來明白些概念性內(nèi)容。 進(jìn)程、線程 進(jìn)程是系統(tǒng)分配的獨(dú)立資源,是 CPU 資源分配的基本單位,進(jìn)程是由一個(gè)或者多個(gè)線程組成的。 線...
摘要:的單線程,與它的用途有關(guān)。特點(diǎn)的顯著特點(diǎn)異步機(jī)制事件驅(qū)動(dòng)。隊(duì)列的讀取輪詢線程,事件的消費(fèi)者,的主角。它將不同的任務(wù)分配給不同的線程,形成一個(gè)事件循環(huán),以異步的方式將任務(wù)的執(zhí)行結(jié)果返回給引擎。 這兩天跟同事同事討論遇到的一個(gè)問題,js中的event loop,引出了chrome與node中運(yùn)行具有setTimeout和Promise的程序時(shí)候執(zhí)行結(jié)果不一樣的問題,從而引出了Nodejs的...
摘要:事件完成,回調(diào)函數(shù)進(jìn)入。主線程從讀取回調(diào)函數(shù)并執(zhí)行。終于執(zhí)行完了,終于從進(jìn)入了主線程執(zhí)行。遇到,立即執(zhí)行。宏任務(wù)微任務(wù)第三輪事件循環(huán)宏任務(wù)執(zhí)行結(jié)束,執(zhí)行兩個(gè)微任務(wù)和。事件循環(huán)事件循環(huán)是實(shí)現(xiàn)異步的一種方法,也是的執(zhí)行機(jī)制。 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機(jī)制,如果讀完本文還不懂,可以揍我。不論你是javascript新手還是老鳥,不論是面試求職,還是日常開發(fā)工作...
閱讀 2137·2021-11-22 15:24
閱讀 2433·2021-09-09 11:53
閱讀 3049·2021-09-04 16:40
閱讀 1647·2019-08-30 15:52
閱讀 3367·2019-08-29 13:47
閱讀 2749·2019-08-26 17:40
閱讀 1560·2019-08-26 13:24
閱讀 2256·2019-08-26 12:01