摘要:回調函數任務完成的時候,需要執行哪段代碼來處理呢當然是回調函數了。事件處理器和回調函數類似。但是特定的事件處理器在瀏覽器進入異步事件驅動階段時就會針對特定的事件注冊。當事件對象返回到執行線程時,事件處理器也會同時進入執行棧中執行。
Event Loop(事件輪詢)機制是一個經常把人搞暈的東東。我不敢說我完全明白,只是在此談談我的淺見。
事件的處理瀏覽器是一個事件驅動(event-driven)架構的軟件。它的UI線程中會不斷產生用戶事件。但是處理事件的JavaScript是單線程執行的,這是一個瀏覽器環境下難以改變的現狀(HTML5 Web Works沒有從本質上改變這個模型)。這意味著:在JavaScript處理某個任務(執行某段代碼)過程中,如果產生了用戶事件,它不會立即被處理。那這種情況該怎么辦呢?
瀏覽器維護了一個“任務隊列”(一個優先隊列數據結構),它是一個瀏覽器進程資源。每當UI線程產生一個事件,事件對象就被當做任務放入任務隊列中(enqueue)。當JavaScript執行線程空閑的時候,隊列中的一個任務就會被送往JavaScript執行線程(dequeue),進行相應的處理。
這個enqueue和dequeue的機制就是“Event Loop”。
但是,不僅用戶事件可以被Event Loop機制處理,還能更多的東西是依賴這個機制的。
異步IO的處理如果沒有異步的理念,這個世界會完全不同:一個耗時的I/O操作(例如HTTP請求)會導致JavaScript執行線程等待,而后續的操作得不到執行。這種情況下,一個耗時的服務器端數據庫操作http請求,會讓JavaScript執行線程阻塞,瀏覽器將長期處于假死狀態,在此期間,其他后續操作(包括用戶的交互事件)得不到響應。
好在瀏覽器不是單線程的。它可以(但不是必須)讓這些I/O任務讓其他線程來托管,這樣就形成了一個執行任務的線程池。但是這些任務的結果總歸要回到JavaScript執行線程上處理,于是這些任務也被放到任務隊列中:需要被托管的任務被放入隊列中(enqueue),已完成的任務會被從隊列中一個個取出(dequeue),回到JavaScript執行線程執行回調。在這些耗時的I/O任務被托管的時候,JavaScript執行線程可以執行其他代碼。
在Node中,這個過程是類似的。本文不表。
這便是異步的原理了。我們看到它同樣依賴Event Loop的機制。
定時器瀏覽器的全局對象window提供了兩個方法,setTimeout和setInterval。這兩個方法其實是調用了瀏覽器的API,將一個任務移除出JavaScript執行線程中,延時處理。
我們現在馬上可以反應過來:這個將要被延時的任務同樣是放到了任務隊列中。在一次Event Loop過程中,它會優先將該時間點下已經到時的延時任務移除出隊列,放入JavaScript執行線程中。這意味著,任務隊列是一個優先隊列。
但是由于JavaScript執行線程的執行時間是不確定的,所以這個延時只是一個大體的值,它取決于JavaScript執行線程的執行時間。
回調函數任務完成的時候,JavaScript需要執行哪段代碼來處理呢?當然是回調函數了。
但是不免奇怪的一點就是:JavaScript中怎么知道要執行的是哪個回調函數呢?答案就是:任務被放入任務隊列的時候,該任務的回調函數會被注冊(注冊到什么地方?需要進一步探究)。這樣,當特定任務完成的時候,任務結果和回調標記會返回給JavaScript執行線程,進入執行棧。
事件處理器與其他任務不同,事件并不是由JavaScript執行線程發出的,而是從UI線程中發出的。
事件處理器和回調函數類似。但是特定的事件處理器在瀏覽器進入異步事件驅動階段時就會針對特定的事件注冊。當事件對象返回到JavaScript執行線程時,事件處理器也會同時進入執行棧中執行。
結束越往后寫,越發現我之前的一些理解有偏差。在學習過程中,我也要多反思,多總結。之前寫的不對的地方,我也會盡早糾正。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90859.html
摘要:講的很清晰,看完之后更深一步的理解了事件循環機制。簡短的概述下總結是一個宏任務源,寫在里面的回調函數會加到宏任務隊列中。至此,一輪的事件循環已經執行完畢,開啟新的一輪事件循環。這就是整段代碼執行情況的理解。 這篇文章真的是好文。講的很清晰,看完之后更深一步的理解了事件循環機制。 http://www.jianshu.com/p/12b9... 簡短的概述下總結 setTimeout是一...
摘要:檢查宏任務隊列,發現有的回調函數立即執行回調函數輸出。接著遇到它的作用是在后將回調函數放到宏任務隊列中這個任務在再下一次的事件循環中執行。 為什么會寫這篇博文呢? 前段時間,和頭條的小伙伴聊天問頭條面試前端會問哪些問題,他稱如果是他面試的話,event-loop肯定是要問的。那天聊了蠻多,event-loop算是給我留下了很深的印象,原因很簡單,因為之前我從未深入了解過,如果是面試的時...
摘要:事件循環首先來看一段代碼運行結果是先輸出,然后大概好幾秒大于一秒以后依次輸出,。原因就在以下這部分代碼中原因就是這部分循環的代碼執行過程超過了秒。而這個循環是放在里面的。 Event-loop 事件循環 首先來看一段代碼 function fn(){ console.log(1) setTimeout(() => { console.log(2) }, 1000) ...
摘要:所以本來快輪到你來辦理業務,會因為老大爺臨時添加的理財業務而往后推。在執行完同步代碼與微任務以后,這時繼續向后查找有木有宏任務。所以輸出了第二次,等到這兩次都執行完畢后才會去檢查有沒有微任務有沒有宏任務。 首先,JavaScript是一個單線程的腳本語言。 所以就是說在一行代碼執行的過程中,必然不會存在同時執行的另一行代碼,就像使用alert()以后進行瘋狂console.log,如...
閱讀 1438·2021-09-22 15:43
閱讀 2154·2019-08-30 15:54
閱讀 1154·2019-08-30 10:51
閱讀 2082·2019-08-29 18:35
閱讀 426·2019-08-26 11:58
閱讀 2476·2019-08-26 11:38
閱讀 2432·2019-08-23 18:35
閱讀 3627·2019-08-23 18:33