摘要:每一個程序都擁有唯一的事件循環,大多數代碼的執行順序是可以根據函數調用棧的規則執行的,而或者不同的事件綁定等中的代碼,則通過隊列來執行。當所有可執行的執行完畢之后,就表示第一次事件循環結束第二次循環會再次從開始執行。
console.log("begin"); setTimeout(function() { console.log("timeout") }); new Promise(function(resolve) { for (let i = 0; i < 3; i++) { if (i == 1) resolve(); console.log(i); } console.log("promise") }).then(function() { console.log("then") }) console.log("end");
上述代碼依次輸出:begin、0、1、2、promise、end、then、timeout
js的一個特點就是單線程,但是很多時候我們仍然需要在不同的時間去執行不同的任務,例如給元素添加點擊事件,設置一個定時器,或者發起ajax請求,因此需要一個異步機制來達到這樣的目的,事件循環機制也因此而來。
每一個js程序都擁有唯一的事件循環,大多數代碼的執行順序是可以根據函數調用棧的規則執行的,而setTimeout/setInterval或者不同的事件綁定(click、mousedown等)中的代碼,則通過隊列來執行。
任務隊列又分為宏任務(macro-task)與微任務(micro-task)兩種,在瀏覽器中,包括:
macro-task:script(整體代碼)、setTimeout/setInterval、I/O、UI rendering等
micro-task:Promise、MutationObserver
事件循環的順序,決定了js代碼的執行順序:
首先從macro-task中的script開始第一次循環。此時全局上下文進入函數調用棧,直到調用棧清空,在這個過程中,如果遇到任務分發器(例如timer、promise),就會將任務放入對應隊列中去
第一次循環時,macro-task中其實只有script,因此函數調用棧清空之后,會直接執行所有的micro-task。當所有可執行的micro-task執行完畢之后,就表示第一次事件循環結束
第二次循環會再次從macro-task開始執行。此時macro-task中的script隊列已經沒有任務了,但是可能會有其他的隊列任務,而micro-task中暫時還沒有任務。此時會先選擇其中一個宏任務隊列,例如setTimeout,將該隊列中所有的任務全部執行完畢,然后再執行此過程中可能產生的微任務。微任務執行完畢之后,再回過頭來執行其他宏任務隊列中的任務。以此類推,直到所有宏任務隊列中的任務都被執行了,并且清空了微任務,第二次循環就會結束
如果在第二次循環過程中,產生了新的宏任務隊列,或者之前宏任務隊列中的任務暫時沒有滿足執行條件,例如延遲時間不夠或者事件沒有被觸發,那么將會繼續以同樣的順序重復循環
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105627.html
摘要:事件處理器,則是當指定事件觸發時,執行的一段代碼。事件循環以一個無限循環的形式啟動,存在于二進制文件里函數的最后,當沒有更多可被執行的事件處理器時,它就退出。 前言 如果你了解過Node.js,那么你一定聽說過事件循環。你一定想知道它為什么那么特殊,并且為什么你需要關注它?此時此刻的你,可能已經寫過許多基于Express.js的后端代碼,但沒有接觸到任何的循環。 在下文中,我們會先在一...
摘要:檢索新的事件執行與相關的回調幾乎所有,除了由定時器調度的一些和將在適當的時候在這里阻塞。在事件循環的每次運行之間,檢查它是否在等待任何異步或定時器,如果沒有,則徹底關閉。 Node.js事件循環、定時器和process.nextTick() 什么是事件循環? 事件循環允許Node.js執行非阻塞I/O操作 — 盡管JavaScript是單線程的 — 通過盡可能將操作卸載到系統內核。 ...
摘要:事件循環的順序,決定代碼執行的順序。輸出第二輪事件循環正式結束三第三輪事件循環第三輪事件循環從宏任務開始。記為遇到,立即執行回調函數放入中注冊,然后被分發到微任務事件隊列中。 1、為什么要有事件循環? 因為js是單線程的,事件循環是js的執行機制,也是js實現異步的一種方法。 既然js是單線程,那就像只有一個窗口的銀行,客戶需要排隊一個一個辦理業務,同理js任務也要一個一個順序執行。如...
摘要:異步請求線程在在連接后是通過瀏覽器新開一個線程請求將檢測到狀態變更時,如果設置有回調函數,異步線程就產生狀態變更事件,將這個回調再放入事件循環隊列中。 基礎:瀏覽器 -- 多進程,每個tab頁獨立一個瀏覽器渲染進程(瀏覽器內核) 每個瀏覽器渲染進程是多線程的,主要包括:GUI渲染線程 JS引擎線程 也稱為JS內核,負責處理Javascript腳本程序。(例如V8引擎) JS引擎線程負...
摘要:的一大特點就是單線程,而這個線程中擁有唯一的一個事件循環。事件循環基本概念代碼的執行過程中,除了依靠函數調用棧來搞定函數的執行順序外,還依靠任務隊列來搞定另外一些代碼的執行。之后全局上下文進入函數調用棧。 JavaScript的一大特點就是單線程,而這個線程中擁有唯一的一個事件循環。 事件循環基本概念 JavaScript代碼的執行過程中,除了依靠函數調用棧來搞定函數的執行順序外,還...
摘要:輪詢投票處理下一次處理的新事件立即設置運行通過注冊的所有回調關閉執行所有的回調工作處理延遲此度量標準測量線程池處理異步任務需要多長時間。高工作時間處理延遲表明繁忙耗盡的線程池。 原文=> What you should know to really understand the Node.js Event Loop Node.js 是一個基于事件的平臺。這就意味著在Node中發生的所...
閱讀 600·2021-10-08 10:20
閱讀 1490·2021-09-23 11:22
閱讀 3214·2019-08-30 15:55
閱讀 1581·2019-08-28 18:25
閱讀 1857·2019-08-28 18:14
閱讀 1230·2019-08-26 11:37
閱讀 2893·2019-08-26 10:18
閱讀 2420·2019-08-23 18:39