js運(yùn)行機(jī)制-事件循環(huán)EventLoop
先來看看一段js代碼:
console.log("script begin") setTimeout(() => { console.log("setTimeout") },0) new Promise((resolve) => { console.log("promise begin") for(let i = 0; i < 1000; i++) { i == 999 && resolve() } }).then(() => { console.log("promise then") }) console.log("script end")
在node命令行里執(zhí)行這段js代碼,輸出的情況為script begin-promise begin——script end——promise then——setTimeout,為什么會這樣呢?我們先來了解幾個概念.
js單線程如何理解js單線程意思就是同一時間只能做一件事,按照先后順序執(zhí)行.那么,為什么JavaScript不能有多個線程呢?這樣能提高效率啊.
JavaScript的單線程,與它的用途有關(guān)。作為瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操作DOM。這決定了它只能是單線程,否則會帶來很復(fù)雜的同步問題。比如,假定JavaScript同時有兩個線程,一個線程在某個DOM節(jié)點(diǎn)上添加內(nèi)容,另一個線程刪除了這個節(jié)點(diǎn),這時瀏覽器應(yīng)該以哪個線程為準(zhǔn)?
所以,為了避免復(fù)雜性,從一誕生,JavaScript就是單線程。
主線程和任務(wù)隊列單線程就意味著,所有任務(wù)需要排隊。所有任務(wù)可以分成兩種,一種是同步任務(wù)(synchronous),另一種是異步任務(wù)(asynchronous)。
同步任務(wù):在主線程上排隊執(zhí)行的任務(wù),只有前一個任務(wù)執(zhí)行完畢,才能執(zhí)行后一個任務(wù);
異步任務(wù):不進(jìn)入主線程、而進(jìn)入"任務(wù)隊列"(task queue)的任務(wù),只有"任務(wù)隊列"通知主線程,某個異步任務(wù)可以執(zhí)行了,該任務(wù)才會進(jìn)入主線程執(zhí)行。
下圖是主線程和任務(wù)隊列的示意圖:
宏任務(wù)和微任務(wù)了解完主線程,還要了解一下任務(wù),任務(wù)有宏任務(wù)(MacroTask)和微任務(wù)(MicroTask)之分。
宏任務(wù)主要有:script代碼段、setTimeout、setInterval、Promise的構(gòu)造函數(shù)、setImmediate、I/O等.
微任務(wù)主要有:process.nextTick和Promise的回調(diào)這兩種情況.
如果宏任務(wù)在本輪Event Loop中執(zhí)行,則微任務(wù)在本輪Event Loop的所有宏任務(wù)結(jié)束后執(zhí)行(Event Loop下面會講到)。下面為宏任務(wù)和微任務(wù)的執(zhí)行示意圖:
Event Loop主線程從"任務(wù)隊列"中讀取事件,這個過程是循環(huán)不斷的,所以整個的這種運(yùn)行機(jī)制又稱為Event Loop(事件循環(huán))
我們再回頭看看開始的一段代碼:
首先任務(wù)進(jìn)入執(zhí)行棧,除了setTimeout,其他的進(jìn)入主線程執(zhí)行,setTimeout則進(jìn)入任務(wù)隊列;
然后主線程里面的任務(wù)又有宏任務(wù)和微任務(wù),先執(zhí)行宏任務(wù),微任務(wù)在所有宏任務(wù)結(jié)束后執(zhí)行;
所以先輸出script begin-promise begin——script end——promise then;
最后主線程讀任務(wù)隊列的異步任務(wù),最后輸出setTimeout
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/109051.html
摘要:宏任務(wù)主要有整體代碼交互事件環(huán)境。按照中的定義告訴瀏覽器你希望執(zhí)行一個動畫,并且要求瀏覽器在下次重繪之前調(diào)用指定的回調(diào)函數(shù)更新動畫??偨Y(jié)我們要記住最重要的兩點(diǎn)是單線程和的循環(huán)機(jī)制。 showImg(https://segmentfault.com/img/bVbsEQs?w=900&h=540); 我們知道 js 是單線程執(zhí)行的,那么異步的代碼 js 是怎么處理的呢?例如下面的代碼是如...
摘要:引言學(xué)習(xí)的時候,經(jīng)常聽人說,即是異步的,又是單線程的。所以我們說是異步單線程的。參考從瀏覽器多進(jìn)程到單線程,運(yùn)行機(jī)制最全面的一次梳理運(yùn)行機(jī)制詳解再談異步機(jī)制詳解運(yùn)行原理解析并發(fā)模型與事件循環(huán) showImg(https://segmentfault.com/img/bVbo4hv?w=1800&h=1000); 引言 學(xué)習(xí)javascipt的時候,經(jīng)常聽人說,javascipt即是異步...
摘要:前沿是基于引擎的運(yùn)行環(huán)境具有事件驅(qū)動非阻塞等特點(diǎn)結(jié)合具有網(wǎng)絡(luò)編程文件系統(tǒng)等服務(wù)端的功能用庫進(jìn)行異步事件處理線程的單線程含義實(shí)際上說的是執(zhí)行同步代碼的主線程一個程序的啟動不止是分配了一個線程,而是我們只能在一個線程執(zhí)行代碼當(dāng)出現(xiàn)資源調(diào)用連接等 前沿 Node.js 是基于V8引擎的javascript運(yùn)行環(huán)境. Node.js具有事件驅(qū)動, 非阻塞I/O等特點(diǎn). 結(jié)合Node API, ...
摘要:異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)異步任務(wù)從任務(wù)隊列回到執(zhí)行棧,回調(diào)函數(shù)就會執(zhí)行。事件循環(huán)主線程從任務(wù)隊列中讀取事件,這個過程是循環(huán)不斷的,所以整個的這種運(yùn)行機(jī)制又稱為。事件循環(huán)事件循環(huán)是指主線程重復(fù)從消息隊列中取消息執(zhí)行的過程。 參考鏈接:這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制https://zhuanlan.zhihu.com/p/...從瀏覽器多進(jìn)程到JS單線程,JS運(yùn)行機(jī)制...
摘要:同時,如果執(zhí)行的過程中發(fā)現(xiàn)其他函數(shù),繼續(xù)入棧然后執(zhí)行。上面我們討論的其實(shí)都是同步代碼,代碼在運(yùn)行的時候只用調(diào)用棧解釋就可以了。 序 Event Loop 這個概念相信大家或多或少都了解過,但是有一次被一個小伙伴問到它具體的原理的時候,感覺自己只知道個大概印象,于是計劃著寫一篇文章,用輸出倒逼輸入,讓自己重新學(xué)習(xí)這個概念,同時也能幫助更多的人理解它~ 概念 JavaScript 是一門 ...
閱讀 3322·2021-10-27 14:20
閱讀 2567·2021-10-08 10:05
閱讀 1658·2021-09-09 09:33
閱讀 2927·2019-08-30 13:16
閱讀 1461·2019-08-29 18:34
閱讀 1209·2019-08-29 10:58
閱讀 1254·2019-08-28 18:22
閱讀 1255·2019-08-26 13:33