摘要:一直以來,對(duì)的執(zhí)行機(jī)制都是模棱兩可,知道今天看了文章這一次,徹底弄懂執(zhí)行機(jī)制和的規(guī)范和實(shí)現(xiàn),才對(duì)的執(zhí)行機(jī)制有了深入的理解,下面是我的學(xué)習(xí)總結(jié)。個(gè)要點(diǎn)是單線程語言是的執(zhí)行機(jī)制,為了實(shí)現(xiàn)主線程的不阻塞,就這么誕生了。
一直以來,對(duì)JS的執(zhí)行機(jī)制都是模棱兩可,知道今天看了文章—《這一次,徹底弄懂JavaScript執(zhí)行機(jī)制》和《Event Loop的規(guī)范和實(shí)現(xiàn)》,才對(duì)JS的執(zhí)行機(jī)制有了深入的理解,下面是我的學(xué)習(xí)總結(jié)。
2個(gè)要點(diǎn)JS是單線程語言
Event Loop是JS的執(zhí)行機(jī)制,為了實(shí)現(xiàn)主線程的不阻塞,Event Loop就這么誕生了。
2個(gè)概念(結(jié)合Browser環(huán)境和Node環(huán)境)task queue(宏任務(wù)隊(duì)列):setTimeout、setInterval、setImmediate、I/O、UI交互事件
microtask queue(微任務(wù)隊(duì)列):Promise、process.nextTick、MutaionObserver
看下圖:
queue可以看成一種數(shù)據(jù)結(jié)構(gòu),用以存儲(chǔ)需要執(zhí)行的函數(shù)
setTimeout等API注冊(cè)的函數(shù),會(huì)進(jìn)入task隊(duì)列
Promise等API注冊(cè)的函數(shù)會(huì)進(jìn)入microtask隊(duì)列
Event Loop執(zhí)行一次,從task隊(duì)列中拉出一個(gè)task執(zhí)行
Event Loop繼續(xù)檢查microtask隊(duì)列是否為空,依次執(zhí)行直至清空隊(duì)列
情景再現(xiàn)JS的執(zhí)行邏輯,就好比只有一個(gè)窗口的銀行,客戶需要一個(gè)一個(gè)排隊(duì)辦理業(yè)務(wù),假如現(xiàn)在排隊(duì)的有兩個(gè)人,第一個(gè)人是辦理銀行卡的,第二個(gè)人是取錢的,下面來個(gè)情景對(duì)話(這就類似上圖的event loop):
客服:請(qǐng)問您辦理什么業(yè)務(wù)?
客戶1:辦理銀行卡。
客服:請(qǐng)先填寫一份申請(qǐng)表。下一位!(此時(shí)客戶1進(jìn)入callback queue)
客服:請(qǐng)問您辦理什么業(yè)務(wù)?
客戶2:取錢
…………
(此時(shí)客戶1已經(jīng)完成申請(qǐng)表填寫,但客戶2還未結(jié)束,那么客戶1還需等待,直到窗口前的這個(gè)客戶辦理結(jié)束)
客戶1:我填好了,給您……
## 實(shí)例練習(xí)1
console.log(1) setTimeout(() => { console.log(2) new Promise(resolve => { console.log(4) resolve() }).then(() => { console.log(5) }) }) new Promise(resolve => { console.log(7) resolve() }).then(() => { console.log(8) }) setTimeout(() => { console.log(9) new Promise(resolve => { console.log(11) resolve() }).then(() => { console.log(12) }) })
分解動(dòng)作:
主進(jìn)程運(yùn)行的代碼首先輸出1、7;
再執(zhí)行一次microtask輸出8;
執(zhí)行了一次task輸出2,4;
再執(zhí)行一次microtask輸出5;
再執(zhí)行另一個(gè)task輸出9、11;
再執(zhí)行一次microtask輸出12
最終結(jié)果:
1、7、8、2、4、5、9、11、12
注意的:在Node環(huán)境下process.nextTick注冊(cè)的函數(shù)優(yōu)先級(jí)高于Promise,大家可以在Node環(huán)境下嘗試下面的例子:
new Promise(resolve => { console.log(1) resolve() }).then(() => { console.log(2) }) new Promise(resolve => { console.log(3) resolve() }).then(() => { console.log(4) }) process.nextTick(() => { console.log(5) }) console.log(6)
執(zhí)行結(jié)果:1、3、6、5、2、4
實(shí)例練習(xí)2setTimeout(() => { console.log(2) }, 2) setTimeout(() => { console.log(1) }, 1) setTimeout(() => { console.log(0) }, 0)
有人說結(jié)果應(yīng)該是0,1,2
但正確結(jié)果是2,1,0。
因?yàn)閟etTimeout最低延遲是4ms,值得注意。
我的博客:http://blog.rnode.me
參考文章:
原文:Event Loop的規(guī)范和實(shí)現(xiàn) 地址:https://juejin.im/post/5a6155126fb9a01cb64edb45 原文:這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制 地址:https://juejin.im/post/59e85eebf265da430d571f89 原文:JavaScript 運(yùn)行機(jī)制詳解:再談Event Loop 地址:http://www.ruanyifeng.com/blog/2014/10/event-loop.html
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/98478.html
摘要:不過其實(shí)簡(jiǎn)書文章評(píng)論里有很多大家的問題以及解答,對(duì)于進(jìn)一步理解文中知識(shí)幫助很大的,算是有點(diǎn)可惜吧。不過也希望能夠?qū)φ趯W(xué)習(xí)前端的你有一些小幫助。如果在閱讀中發(fā)現(xiàn)了一些錯(cuò)誤,請(qǐng)?jiān)谠u(píng)論里告訴我,我會(huì)及時(shí)更改。 前端基礎(chǔ)進(jìn)階(一):內(nèi)存空間詳細(xì)圖解 前端基礎(chǔ)進(jìn)階(二):執(zhí)行上下文詳細(xì)圖解 前端基礎(chǔ)進(jìn)階(三):變量對(duì)象詳解 前端基礎(chǔ)進(jìn)階(四):詳細(xì)圖解作用域鏈與閉包 前端基礎(chǔ)進(jìn)階(五):全方位...
摘要:之前文章詳細(xì)介紹了的使用,不了解的查看進(jìn)階期。不同的引擎有不同的限制,核心限制在,有些引擎會(huì)拋出異常,有些不拋出異常但丟失多余參數(shù)。存儲(chǔ)的對(duì)象能動(dòng)態(tài)增多和減少,并且可以存儲(chǔ)任何值。這邊采用方法來實(shí)現(xiàn),拼成一個(gè)函數(shù)。 之前文章詳細(xì)介紹了 this 的使用,不了解的查看【進(jìn)階3-1期】。 call() 和 apply() call() 方法調(diào)用一個(gè)函數(shù), 其具有一個(gè)指定的 this 值和分...
摘要:使用指定的參數(shù)調(diào)用構(gòu)造函數(shù),并將綁定到新創(chuàng)建的對(duì)象。由構(gòu)造函數(shù)返回的對(duì)象就是表達(dá)式的結(jié)果。情況返回以外的基本類型實(shí)例中只能訪問到構(gòu)造函數(shù)中的屬性,和情況完全相反,結(jié)果相當(dāng)于沒有返回值。 定義 new 運(yùn)算符創(chuàng)建一個(gè)用戶定義的對(duì)象類型的實(shí)例或具有構(gòu)造函數(shù)的內(nèi)置對(duì)象的實(shí)例。 ——(來自于MDN) 舉個(gè)栗子 function Car(color) { this.color = co...
摘要:一棧數(shù)據(jù)結(jié)構(gòu)與不同,中并沒有嚴(yán)格意義上區(qū)分棧內(nèi)存與堆內(nèi)存。引用數(shù)據(jù)類型的值是保存在堆內(nèi)存中的對(duì)象。不允許直接訪問堆內(nèi)存中的位置,因此我們不能直接操作對(duì)象的堆內(nèi)存空間。為了更好的搞懂變量對(duì)象與堆內(nèi)存,我們可以結(jié)合以下例子與圖解進(jìn)行理解。 showImg(https://segmentfault.com/img/remote/1460000009784102?w=1240&h=683); ...
摘要:報(bào)文用于協(xié)議交互的信息被稱為報(bào)文。現(xiàn)在出現(xiàn)的各種首部字段及狀態(tài)碼稍后會(huì)闡述。狀態(tài)碼響應(yīng)報(bào)文包含了多個(gè)范圍的內(nèi)容使用。如果服務(wù)器無法響應(yīng)范圍請(qǐng)求,則會(huì)返回狀態(tài)碼和完整的實(shí)體內(nèi)容。 showImg(https://segmentfault.com/img/bVbthNL?w=900&h=500); http報(bào)文 用于HTTP協(xié)議交互的信息被稱為HTTP報(bào)文。請(qǐng)求端的http報(bào)文叫做請(qǐng)求報(bào)文...
閱讀 2104·2021-11-23 10:06
閱讀 3456·2021-11-11 16:54
閱讀 3336·2019-08-29 17:31
閱讀 3563·2019-08-29 17:05
閱讀 2165·2019-08-26 13:36
閱讀 2154·2019-08-26 12:17
閱讀 519·2019-08-26 12:12
閱讀 1668·2019-08-26 10:19