成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript的event-loop

aboutU / 568人閱讀

摘要:從誕生之日起就是一門(mén)單線程的非阻塞的腳本語(yǔ)言。這意味著這些線程實(shí)際上應(yīng)屬于主線程的子線程。所以嚴(yán)格來(lái)講這些線程并沒(méi)有完整的功能,也因此這項(xiàng)技術(shù)并非改變了語(yǔ)言的單線程本質(zhì)。函數(shù)執(zhí)行棧和事件隊(duì)列

瀏覽器渲染

從耗時(shí)的角度,瀏覽器請(qǐng)求、加載、渲染一個(gè)頁(yè)面,時(shí)間花在下面五件事情上:
1.DNS 查詢
2.TCP 連接
3.HTTP 請(qǐng)求即響應(yīng)
4.服務(wù)器響應(yīng)
5.客戶端渲染

這里重點(diǎn)討論第五個(gè)部分,即瀏覽器對(duì)內(nèi)容的渲染,這一部分(渲染樹(shù)構(gòu)建,布局和繪制),又可以分為下面的五個(gè)部分。

1.處理 HTML 標(biāo)記并構(gòu)建 DOM 樹(shù)。
2.處理 CSS 標(biāo)記并構(gòu)建 CSSOM 樹(shù)。
3.將 DOM 與 CSSOM 合并成一個(gè)渲染樹(shù)。
4.根據(jù)渲染樹(shù)來(lái)布局,以計(jì)算每個(gè)節(jié)點(diǎn)的幾何信息。
5.將各個(gè)節(jié)點(diǎn)繪制到屏幕上。

這些并不是本文正文,只是說(shuō)在完成以上過(guò)程之后,整個(gè)頁(yè)面就已經(jīng)出來(lái)了,這個(gè)時(shí)候?yàn)g覽器是否就已經(jīng)處于空閑狀態(tài)了呢(不考慮動(dòng)畫(huà)、交互等處理)?接下來(lái)就是本文的重點(diǎn)了。

堆、棧、隊(duì)列

了解重點(diǎn)之前我們先了解一點(diǎn)簡(jiǎn)單的基礎(chǔ)知識(shí),堆、棧、隊(duì)列;

對(duì)象被分配在一個(gè)堆中,即用以表示一個(gè)大部分非結(jié)構(gòu)化的內(nèi)存區(qū)域。

這是在程序運(yùn)行時(shí)需要給對(duì)new操作產(chǎn)生的對(duì)象分配存儲(chǔ)空間,是一個(gè)沒(méi)有特別限制的存儲(chǔ)空間。

函數(shù)調(diào)用形成一個(gè)棧幀;

棧的特點(diǎn):先進(jìn)后出(First in, last out)函數(shù)執(zhí)行棧過(guò)程;可以看成是每次函數(shù)first運(yùn)行時(shí),將函數(shù)入棧,此時(shí)函數(shù)中的其他運(yùn)行函數(shù)(second函數(shù))需要再次入棧,執(zhí)行完該second函數(shù)之后,該second函數(shù)將會(huì)出棧,繼而完成first的執(zhí)行,執(zhí)行完成后,first將會(huì)出棧;

隊(duì)列

隊(duì)列是一種和棧不一樣的數(shù)據(jù)結(jié)構(gòu),類(lèi)似管道,先進(jìn)入的將會(huì)現(xiàn)出來(lái),和棧是相反的。

event-loop
javascript從誕生之日起就是一門(mén)單線程的非阻塞的腳本語(yǔ)言。這是由其最初的用途來(lái)決定的:與瀏覽器交互。
單線程意味著,javascript代碼在執(zhí)行的任何時(shí)候,都只有一個(gè)主線程來(lái)處理所有的任務(wù)。
而非阻塞則是當(dāng)代碼需要進(jìn)行一項(xiàng)異步任務(wù)(無(wú)法立刻返回結(jié)果,需要花一定時(shí)間才能返回的任務(wù),如I/O事件)的時(shí)候,主線程會(huì)掛起(pending)這個(gè)任務(wù),然后在異步任務(wù)返回結(jié)果的時(shí)候再根據(jù)一定規(guī)則去執(zhí)行相應(yīng)的回調(diào)。
單線程是必要的,也是javascript這門(mén)語(yǔ)言的基石,原因之一在其最初也是最主要的執(zhí)行環(huán)境——瀏覽器中,我們需要進(jìn)行各種各樣的dom操作。試想一下 如果javascript是多線程的,那么當(dāng)兩個(gè)線程同時(shí)對(duì)dom進(jìn)行一項(xiàng)操作,例如一個(gè)向其添加事件,而另一個(gè)刪除了這個(gè)dom,此時(shí)該如何處理呢?因此,為了保證不會(huì) 發(fā)生類(lèi)似于這個(gè)例子中的情景,javascript選擇只用一個(gè)主線程來(lái)執(zhí)行代碼,這樣就保證了程序執(zhí)行的一致性。
當(dāng)然,現(xiàn)如今人們也意識(shí)到,單線程在保證了執(zhí)行順序的同時(shí)也限制了javascript的效率,因此開(kāi)發(fā)出了web worker技術(shù)。這項(xiàng)技術(shù)號(hào)稱讓javascript成為一門(mén)多線程語(yǔ)言。
然而,使用web worker技術(shù)開(kāi)的多線程有著諸多限制,例如:所有新線程都受主線程的完全控制,不能獨(dú)立執(zhí)行。這意味著這些“線程” 實(shí)際上應(yīng)屬于主線程的子線程。另外,這些子線程并沒(méi)有執(zhí)行I/O操作的權(quán)限,只能為主線程分擔(dān)一些諸如計(jì)算等任務(wù)。所以嚴(yán)格來(lái)講這些線程并沒(méi)有完整的功能,也因此這項(xiàng)技術(shù)并非改變了javascript語(yǔ)言的單線程本質(zhì)。
可以預(yù)見(jiàn),未來(lái)的javascript也會(huì)一直是一門(mén)單線程的語(yǔ)言。

那么為了能夠很好地提高的腳本的效率,故而設(shè)計(jì)的時(shí)候有一個(gè)非常有趣的特性是事件循環(huán)模型,與許多其他語(yǔ)言不同,它永不阻塞。 處理 I/O 通常通過(guò)事件和回調(diào)來(lái)執(zhí)行,所以當(dāng)一個(gè)應(yīng)用正等待IndexedDB查詢返回或者一個(gè) XHR 請(qǐng)求返回時(shí),它仍然可以處理其它事情,如用戶輸入。

macro task與micro task

首先執(zhí)行script,script被稱為全局任務(wù),也屬于macrotask;

當(dāng)macrotask執(zhí)行完以下,執(zhí)行所有的微任務(wù);

微任務(wù)全部執(zhí)行完,再取任務(wù)隊(duì)列中的一個(gè)宏任務(wù)執(zhí)行。

宏任務(wù)包括:script, setTimeout, setInterval, setImmediate, I/O,UI rendering,requestAnimationFrame
微任務(wù)包括:process.nextTick(node api), 原生Promise(有些實(shí)現(xiàn)的promise將then方法放到了宏任務(wù)中),Object.observe(已廢棄), MutationObserver

執(zhí)行順序

所有的宏任務(wù)放在一個(gè)宏任務(wù)隊(duì)列(即任務(wù)隊(duì)列),處理完一個(gè)宏任務(wù)(從sccript開(kāi)始),將微任務(wù)隊(duì)列(包含當(dāng)時(shí)所有的微任務(wù))壓入任務(wù)隊(duì)列(宏任務(wù)隊(duì)列)并執(zhí)行,之后再取下一個(gè)任務(wù)隊(duì)列(宏任務(wù))中的宏任務(wù)。

https://juejin.im/post/5b6d58...

https://github.com/ccforward/... 【函數(shù)執(zhí)行棧和事件隊(duì)列】

https://zhuanlan.zhihu.com/p/...

https://jakearchibald.com/201...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97048.html

相關(guān)文章

  • 徹底搞懂瀏覽器Event-loop

    摘要:檢查宏任務(wù)隊(duì)列,發(fā)現(xiàn)有的回調(diào)函數(shù)立即執(zhí)行回調(diào)函數(shù)輸出。接著遇到它的作用是在后將回調(diào)函數(shù)放到宏任務(wù)隊(duì)列中這個(gè)任務(wù)在再下一次的事件循環(huán)中執(zhí)行。 為什么會(huì)寫(xiě)這篇博文呢? 前段時(shí)間,和頭條的小伙伴聊天問(wèn)頭條面試前端會(huì)問(wèn)哪些問(wèn)題,他稱如果是他面試的話,event-loop肯定是要問(wèn)的。那天聊了蠻多,event-loop算是給我留下了很深的印象,原因很簡(jiǎn)單,因?yàn)橹拔覐奈瓷钊肓私膺^(guò),如果是面試的時(shí)...

    source 評(píng)論0 收藏0
  • 理解Event-Loop

    摘要:回調(diào)函數(shù)任務(wù)完成的時(shí)候,需要執(zhí)行哪段代碼來(lái)處理呢當(dāng)然是回調(diào)函數(shù)了。事件處理器和回調(diào)函數(shù)類(lèi)似。但是特定的事件處理器在瀏覽器進(jìn)入異步事件驅(qū)動(dòng)階段時(shí)就會(huì)針對(duì)特定的事件注冊(cè)。當(dāng)事件對(duì)象返回到執(zhí)行線程時(shí),事件處理器也會(huì)同時(shí)進(jìn)入執(zhí)行棧中執(zhí)行。 Event Loop(事件輪詢)機(jī)制是一個(gè)經(jīng)常把人搞暈的東東。我不敢說(shuō)我完全明白,只是在此談?wù)勎业臏\見(jiàn)。 事件的處理 瀏覽器是一個(gè)事件驅(qū)動(dòng)(event-dr...

    blair 評(píng)論0 收藏0
  • 淺析 event-loop 事件輪詢

    摘要:如果執(zhí)行的準(zhǔn)備時(shí)間大于了,因?yàn)閳?zhí)行同步代碼后,定時(shí)器的回調(diào)已經(jīng)被放入隊(duì)列,所以會(huì)先執(zhí)行隊(duì)列。 showImg(https://segmentfault.com/img/remote/1460000018998584); 閱讀原文 瀏覽器中的事件輪詢 JavaScript 是一門(mén)單線程語(yǔ)言,之所以說(shuō)是單線程,是因?yàn)樵跒g覽器中,如果是多線程,并且兩個(gè)線程同時(shí)操作了同一個(gè) Dom 元素,...

    2501207950 評(píng)論0 收藏0
  • Event-loop事件循環(huán)

    摘要:事件循環(huán)首先來(lái)看一段代碼運(yùn)行結(jié)果是先輸出,然后大概好幾秒大于一秒以后依次輸出,。原因就在以下這部分代碼中原因就是這部分循環(huán)的代碼執(zhí)行過(guò)程超過(guò)了秒。而這個(gè)循環(huán)是放在里面的。 Event-loop 事件循環(huán) 首先來(lái)看一段代碼 function fn(){ console.log(1) setTimeout(() => { console.log(2) }, 1000) ...

    MingjunYang 評(píng)論0 收藏0
  • 微任務(wù)、宏任務(wù)與Event-Loop

    摘要:所以本來(lái)快輪到你來(lái)辦理業(yè)務(wù),會(huì)因?yàn)槔洗鬆斉R時(shí)添加的理財(cái)業(yè)務(wù)而往后推。在執(zhí)行完同步代碼與微任務(wù)以后,這時(shí)繼續(xù)向后查找有木有宏任務(wù)。所以輸出了第二次,等到這兩次都執(zhí)行完畢后才會(huì)去檢查有沒(méi)有微任務(wù)有沒(méi)有宏任務(wù)。 首先,JavaScript是一個(gè)單線程的腳本語(yǔ)言。 所以就是說(shuō)在一行代碼執(zhí)行的過(guò)程中,必然不會(huì)存在同時(shí)執(zhí)行的另一行代碼,就像使用alert()以后進(jìn)行瘋狂console.log,如...

    Nekron 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<