亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

理解Event-Loop

blair / 1891人閱讀

摘要:回調(diào)函數(shù)任務(wù)完成的時(shí)候,需要執(zhí)行哪段代碼來(lái)處理呢當(dāng)然是回調(diào)函數(shù)了。事件處理器和回調(diào)函數(shù)類似。但是特定的事件處理器在瀏覽器進(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-driven)架構(gòu)的軟件。它的UI線程中會(huì)不斷產(chǎn)生用戶事件。但是處理事件的JavaScript是單線程執(zhí)行的,這是一個(gè)瀏覽器環(huán)境下難以改變的現(xiàn)狀(HTML5 Web Works沒(méi)有從本質(zhì)上改變這個(gè)模型)。這意味著:在JavaScript處理某個(gè)任務(wù)(執(zhí)行某段代碼)過(guò)程中,如果產(chǎn)生了用戶事件,它不會(huì)立即被處理。那這種情況該怎么辦呢?

瀏覽器維護(hù)了一個(gè)“任務(wù)隊(duì)列”(一個(gè)優(yōu)先隊(duì)列數(shù)據(jù)結(jié)構(gòu)),它是一個(gè)瀏覽器進(jìn)程資源。每當(dāng)UI線程產(chǎn)生一個(gè)事件,事件對(duì)象就被當(dāng)做任務(wù)放入任務(wù)隊(duì)列中(enqueue)。當(dāng)JavaScript執(zhí)行線程空閑的時(shí)候,隊(duì)列中的一個(gè)任務(wù)就會(huì)被送往JavaScript執(zhí)行線程(dequeue),進(jìn)行相應(yīng)的處理。

這個(gè)enqueue和dequeue的機(jī)制就是“Event Loop”。

但是,不僅用戶事件可以被Event Loop機(jī)制處理,還能更多的東西是依賴這個(gè)機(jī)制的。

異步IO的處理

如果沒(méi)有異步的理念,這個(gè)世界會(huì)完全不同:一個(gè)耗時(shí)的I/O操作(例如HTTP請(qǐng)求)會(huì)導(dǎo)致JavaScript執(zhí)行線程等待,而后續(xù)的操作得不到執(zhí)行。這種情況下,一個(gè)耗時(shí)的服務(wù)器端數(shù)據(jù)庫(kù)操作http請(qǐng)求,會(huì)讓JavaScript執(zhí)行線程阻塞,瀏覽器將長(zhǎng)期處于假死狀態(tài),在此期間,其他后續(xù)操作(包括用戶的交互事件)得不到響應(yīng)。

好在瀏覽器不是單線程的。它可以(但不是必須)讓這些I/O任務(wù)讓其他線程來(lái)托管,這樣就形成了一個(gè)執(zhí)行任務(wù)的線程池。但是這些任務(wù)的結(jié)果總歸要回到JavaScript執(zhí)行線程上處理,于是這些任務(wù)也被放到任務(wù)隊(duì)列中:需要被托管的任務(wù)被放入隊(duì)列中(enqueue),已完成的任務(wù)會(huì)被從隊(duì)列中一個(gè)個(gè)取出(dequeue),回到JavaScript執(zhí)行線程執(zhí)行回調(diào)。在這些耗時(shí)的I/O任務(wù)被托管的時(shí)候,JavaScript執(zhí)行線程可以執(zhí)行其他代碼。

在Node中,這個(gè)過(guò)程是類似的。本文不表。

這便是異步的原理了。我們看到它同樣依賴Event Loop的機(jī)制。

定時(shí)器

瀏覽器的全局對(duì)象window提供了兩個(gè)方法,setTimeout和setInterval。這兩個(gè)方法其實(shí)是調(diào)用了瀏覽器的API,將一個(gè)任務(wù)移除出JavaScript執(zhí)行線程中,延時(shí)處理。

我們現(xiàn)在馬上可以反應(yīng)過(guò)來(lái):這個(gè)將要被延時(shí)的任務(wù)同樣是放到了任務(wù)隊(duì)列中。在一次Event Loop過(guò)程中,它會(huì)優(yōu)先將該時(shí)間點(diǎn)下已經(jīng)到時(shí)的延時(shí)任務(wù)移除出隊(duì)列,放入JavaScript執(zhí)行線程中。這意味著,任務(wù)隊(duì)列是一個(gè)優(yōu)先隊(duì)列。

但是由于JavaScript執(zhí)行線程的執(zhí)行時(shí)間是不確定的,所以這個(gè)延時(shí)只是一個(gè)大體的值,它取決于JavaScript執(zhí)行線程的執(zhí)行時(shí)間。

回調(diào)函數(shù)

任務(wù)完成的時(shí)候,JavaScript需要執(zhí)行哪段代碼來(lái)處理呢?當(dāng)然是回調(diào)函數(shù)了。

但是不免奇怪的一點(diǎn)就是:JavaScript中怎么知道要執(zhí)行的是哪個(gè)回調(diào)函數(shù)呢?答案就是:任務(wù)被放入任務(wù)隊(duì)列的時(shí)候,該任務(wù)的回調(diào)函數(shù)會(huì)被注冊(cè)(注冊(cè)到什么地方?需要進(jìn)一步探究)。這樣,當(dāng)特定任務(wù)完成的時(shí)候,任務(wù)結(jié)果和回調(diào)標(biāo)記會(huì)返回給JavaScript執(zhí)行線程,進(jìn)入執(zhí)行棧。

事件處理器

與其他任務(wù)不同,事件并不是由JavaScript執(zhí)行線程發(fā)出的,而是從UI線程中發(fā)出的。

事件處理器和回調(diào)函數(shù)類似。但是特定的事件處理器在瀏覽器進(jìn)入異步事件驅(qū)動(dòng)階段時(shí)就會(huì)針對(duì)特定的事件注冊(cè)。當(dāng)事件對(duì)象返回到JavaScript執(zhí)行線程時(shí),事件處理器也會(huì)同時(shí)進(jìn)入執(zhí)行棧中執(zhí)行。

結(jié)束

越往后寫,越發(fā)現(xiàn)我之前的一些理解有偏差。在學(xué)習(xí)過(guò)程中,我也要多反思,多總結(jié)。之前寫的不對(duì)的地方,我也會(huì)盡早糾正。

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

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

相關(guān)文章

  • 結(jié)合microtask和macrotask理解event-loop

    摘要:講的很清晰,看完之后更深一步的理解了事件循環(huán)機(jī)制。簡(jiǎn)短的概述下總結(jié)是一個(gè)宏任務(wù)源,寫在里面的回調(diào)函數(shù)會(huì)加到宏任務(wù)隊(duì)列中。至此,一輪的事件循環(huán)已經(jīng)執(zhí)行完畢,開(kāi)啟新的一輪事件循環(huán)。這就是整段代碼執(zhí)行情況的理解。 這篇文章真的是好文。講的很清晰,看完之后更深一步的理解了事件循環(huán)機(jī)制。 http://www.jianshu.com/p/12b9... 簡(jiǎn)短的概述下總結(jié) setTimeout是一...

    sarva 評(píng)論0 收藏0
  • 徹底搞懂瀏覽器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ì)寫這篇博文呢? 前段時(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事件循環(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元查看
<