摘要:理解的運(yùn)行機(jī)制是日常編碼必須要掌握的技能。什么是事件循環(huán)為了協(xié)調(diào)事件用戶(hù)交互腳本渲染和網(wǎng)絡(luò)處理等行為,防止主線(xiàn)程阻塞。主線(xiàn)程從任務(wù)隊(duì)列中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱(chēng)為事件循環(huán)。
Javascript是一種單線(xiàn)程開(kāi)發(fā)語(yǔ)言。理解Javascript的運(yùn)行機(jī)制是日常編碼必須要掌握的技能。為什么是單線(xiàn)程?
JavaScript的主要用途是與用戶(hù)交互,以及操作DOM。這決定了它只能是單線(xiàn)程,否則會(huì)帶來(lái)很復(fù)雜的同步問(wèn)題。
假設(shè):如果JavaScript支持多線(xiàn)程,一個(gè)線(xiàn)程在某個(gè)DOM節(jié)點(diǎn)上添加內(nèi)容,另外一個(gè)線(xiàn)程刪除了這個(gè)節(jié)點(diǎn),那么瀏覽器該以哪個(gè)線(xiàn)程為準(zhǔn)呢?
單線(xiàn)程的缺點(diǎn)單線(xiàn)程就意味著容易發(fā)生線(xiàn)程等待資源,cpu空閑,而其他任務(wù)一直等待的問(wèn)題。
什么是Event Loop(事件循環(huán))為了協(xié)調(diào)事件、用戶(hù)交互、腳本、UI 渲染和網(wǎng)絡(luò)處理等行為,防止主線(xiàn)程阻塞。于是Javascript設(shè)計(jì)者將所有任務(wù)分為兩種,一種是同步任務(wù),一種是異步任務(wù)
同步任務(wù)指的是,在主線(xiàn)程上排隊(duì)執(zhí)行的任務(wù)
同步任務(wù)只有前一個(gè)任務(wù)執(zhí)行完畢,才能執(zhí)行下一個(gè)任務(wù)。
同步任務(wù)都在主線(xiàn)程上執(zhí)行,形成一個(gè)執(zhí)行棧
每次執(zhí)行棧執(zhí)行的代碼就是一個(gè)宏任務(wù)
異步任務(wù)指的是,不進(jìn)入主線(xiàn)程,而進(jìn)入任務(wù)隊(duì)列的任務(wù)。
只要指定過(guò)回調(diào)函數(shù),這些事件發(fā)生時(shí)就會(huì)進(jìn)入"任務(wù)隊(duì)列"(比如鼠標(biāo)點(diǎn)擊...等)
一旦執(zhí)行棧中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取“任務(wù)隊(duì)列”。
任務(wù)隊(duì)列是一個(gè)先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),排在前面的事件,優(yōu)先被主線(xiàn)程讀取。
"主線(xiàn)程"從"任務(wù)隊(duì)列"中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱(chēng)為Event Loop(事件循環(huán))。
宏任務(wù)和微任務(wù)根據(jù)規(guī)范:每個(gè)任務(wù)都有一個(gè)任務(wù)源(task source),源自同一個(gè)任務(wù)源的 task 必須放到同一個(gè)任務(wù)隊(duì)列,從不同源來(lái)的則被添加到不同隊(duì)列,所以有了宏任務(wù)(macro)task和微任務(wù)(micro)task。
瀏覽器為了能夠使得JS內(nèi)部(macro)task與DOM任務(wù)能夠有序的執(zhí)行,會(huì)在一個(gè)task執(zhí)行結(jié)束后,在下一個(gè)(macro)task 執(zhí)行開(kāi)始前,對(duì)頁(yè)面進(jìn)行重新渲染,
每次執(zhí)行完一個(gè)宏任務(wù)之后,會(huì)去檢查是否存在微任務(wù);如果有,則執(zhí)行微任務(wù)直至清空微任務(wù)隊(duì)列,如果在微任務(wù)執(zhí)行期間微任務(wù)隊(duì)列加入了新的微任務(wù),會(huì)將新的微任務(wù)加入隊(duì)列尾部,之后也會(huì)被執(zhí)行。
根據(jù)上述總結(jié)流程為:
附(宏/微任務(wù)清單):
宏任務(wù)(macro)task主要有: script(整體代碼)、setTimeout、setInterval、I/O、UI交互事件、postMessage、MessageChannel、setImmediate(Node.js 環(huán)境)
微任務(wù)(micro)task主要有: Promise.then、MutaionObserver、process.nextTick(Node.js 環(huán)境)
requestAnimationFrame 既不屬于宏任務(wù), 也不屬于微任務(wù)
目前宏任務(wù)和微任務(wù)在各瀏覽器執(zhí)行都有差異,最后提議promise為微任務(wù)
setTimeout(function(){ console.log("1"); }); new Promise(function(resolve){ console.log("2"); resolve(); }).then(function(){ console.log("3"); }); console.log("4");
以上案例會(huì)輸出 2 4 3 1
結(jié)果解析:
JavaScript執(zhí)行主線(xiàn)程任務(wù):輸出 2 4
附:Promise構(gòu)造器內(nèi)部是同步任務(wù)
執(zhí)行微任務(wù)隊(duì)列:輸入 3
第一個(gè)宏任務(wù)結(jié)束,進(jìn)入setTimeout回調(diào):輸出 1
End持續(xù)更新中 來(lái)Github 點(diǎn)顆?吧返回主頁(yè)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/109293.html
摘要:異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)異步任務(wù)從任務(wù)隊(duì)列回到執(zhí)行棧,回調(diào)函數(shù)就會(huì)執(zhí)行。事件循環(huán)主線(xiàn)程從任務(wù)隊(duì)列中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱(chēng)為。事件循環(huán)事件循環(huán)是指主線(xiàn)程重復(fù)從消息隊(duì)列中取消息執(zhí)行的過(guò)程。 參考鏈接:這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制https://zhuanlan.zhihu.com/p/...從瀏覽器多進(jìn)程到JS單線(xiàn)程,JS運(yùn)行機(jī)制...
摘要:主線(xiàn)程從任務(wù)隊(duì)列中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱(chēng)為事件循環(huán)。上面也提到,在到達(dá)指定時(shí)間時(shí),定時(shí)器就會(huì)將相應(yīng)回調(diào)函數(shù)插入任務(wù)隊(duì)列尾部。這就是定時(shí)器功能。關(guān)于定時(shí)器的重要補(bǔ)充定時(shí)器包括與兩個(gè)方法。 一、引子 本文介紹JavaScript運(yùn)行機(jī)制,這一部分比較抽象,我們先從一道面試題入手: console.log(1); setTimeout(function()...
摘要:主線(xiàn)程從任務(wù)隊(duì)列中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱(chēng)為事件循環(huán)。上面也提到,在到達(dá)指定時(shí)間時(shí),定時(shí)器就會(huì)將相應(yīng)回調(diào)函數(shù)插入任務(wù)隊(duì)列尾部。這就是定時(shí)器功能。關(guān)于定時(shí)器的重要補(bǔ)充定時(shí)器包括與兩個(gè)方法。 一、引子 本文介紹JavaScript運(yùn)行機(jī)制,這一部分比較抽象,我們先從一道面試題入手: console.log(1); setTimeout(function()...
摘要:主線(xiàn)程從任務(wù)隊(duì)列中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱(chēng)為事件循環(huán)。上面也提到,在到達(dá)指定時(shí)間時(shí),定時(shí)器就會(huì)將相應(yīng)回調(diào)函數(shù)插入任務(wù)隊(duì)列尾部。這就是定時(shí)器功能。關(guān)于定時(shí)器的重要補(bǔ)充定時(shí)器包括與兩個(gè)方法。 一、引子 本文介紹JavaScript運(yùn)行機(jī)制,這一部分比較抽象,我們先從一道面試題入手: console.log(1); setTimeout(function()...
摘要:主線(xiàn)程不斷重復(fù)上面的三步,此過(guò)程也就是常說(shuō)的事件循環(huán)。所以主線(xiàn)程代碼執(zhí)行時(shí)間過(guò)長(zhǎng),會(huì)阻塞事件循環(huán)的執(zhí)行。參考資料這一次,徹底弄懂執(zhí)行機(jī)制任務(wù)隊(duì)列的順序機(jī)制事件循環(huán)搞懂異步事件輪詢(xún)與中的事件循環(huán) 1. 說(shuō)明 讀過(guò)本文章后,您能知道: JavaScript代碼在瀏覽器中的執(zhí)行機(jī)制和事件循環(huán) 面試中經(jīng)常遇到的代碼輸出順序問(wèn)題 首先通過(guò)一段代碼來(lái)驗(yàn)證你是否了解代碼輸出順序,如果你不知道輸出...
閱讀 3960·2021-11-17 09:33
閱讀 3298·2021-10-08 10:05
閱讀 3124·2021-09-22 15:36
閱讀 1152·2021-09-06 15:02
閱讀 2780·2019-08-29 12:45
閱讀 1603·2019-08-26 13:40
閱讀 3411·2019-08-26 13:37
閱讀 434·2019-08-26 13:37