大家好!
今天,正如標題所說,我將討論事件循環。
這不是面試官經常直接詢問的話題(我只記得有兩次他們讓我解釋事件循環)。但是,在大多數採訪中,他們會提出與之相關的問題。例如:
如果您了解事件循環的工作原理,那麼所有這些問題都會更容易回答。
老實說:這個話題不是我最喜歡的。我更喜歡詢問有關程式碼行為的問題,而不是解釋事件循環如何連續工作 10 分鐘。 ?
讓我們開始吧! ?
## 問題
1.什麼是事件循環?
2. 範例
簡短回答:
事件循環負責處理 JavaScript 執行階段中的非同步任務。
說實話,我認為這個答案不足以滿足面試官詢問事件循環的好奇心。因此,在這篇文章中,我想更深入地探討這個主題。
不僅僅是了解概念,了解如何它的工作原理也很重要。這就是為什麼我在最後添加了一些示例。
JavaScript 有一個基於事件循環的執行時間,負責處理任務。每種語言都有獨特的運行時,需要注意的重要一點是 JavaScript 是單執行緒。
單執行緒意味著JavaScript 一次只能處理一項任務。這就是為什麼事件循環在 JavaScript 中如此重要;儘管存在單執行緒限制,它仍然有助於有效地管理任務。
為了更好地理解事件循環,我們先來看看它的主要組成部分:
呼叫堆疊是一種資料結構,用來追蹤我們所呼叫的函數。你可以把它想像成一堆盤子:當一個函數被呼叫時,它被加到堆疊中,當它完成時,它被從堆疊中刪除。
呼叫堆疊遵循LIFO(後進先出) 原則,這意味著JavaScript 按照函數的堆疊順序執行函數— 從最上面的項目到底部,一個位於一次(記住,JavaScript 是單線程的)。
在 JavaScript 的執行時間中,我們有佇列,它保存要處理的任務清單。這些佇列中的任務會等待,直到呼叫堆疊為空。
任務佇列(或回調佇列):此佇列儲存諸如 setTimeout() 和 setInterval() 呼叫之類的任務。這裡的任務是在呼叫堆疊為空並且微任務佇列中的所有任務都處理完之後進行處理的。在 MDN 上查看儲存在此佇列中的任務的更多範例。
微任務佇列: 此佇列的優先權高於任務佇列。它包括微任務(例如 Promise 回調)和非同步函數(例如 process.nextTick() 和非同步函數)。
任務佇列以FIFO(先進先出)為基礎工作,這表示任務按照新增的順序進行處理,但僅在微任務之後進行佇列已空。
事件循環是一種管理非同步程式碼執行的機制。它觀察呼叫堆疊以及呼叫堆疊和佇列(任務佇列和微任務佇列)之間的協調,以保持程式碼順利運行。
讓我們一步步過一遍事件循環過程。請參閱下圖以獲得直觀表示。
在此範例中:
依照這個順序-呼叫堆疊,然後微任務佇列,最後任務佇列-事件循環幫助JavaScript有效處理非同步程式碼,即使在它的單線程環境。
現在我們了解了事件循環的工作原理以及任務的優先順序如何確定,讓我們來看一些範例。
const a = new Promise(function showA(resolve){ console.log('A'); resolve('B'); }); setTimeout(function showC() { console.log('C'); }, 0); a.then(function showB(b) { console.log(b); }); const d = function showD() { console.log('D'); }; d();
在繼續之前,試著考慮一下輸出的順序。
✨你期望它是什麼? ✨
讓我們分解程式碼的每個部分來理解為什麼我們會得到這個輸出。
1。創造承諾
const a = new Promise(function showA(resolve) { console.log('A'); resolve('B'); });
2。 setTimeout 呼叫
setTimeout(function showC() { console.log('C'); }, 0);
3。 a.then 回呼
const a = new Promise(function showA(resolve){ console.log('A'); resolve('B'); }); setTimeout(function showC() { console.log('C'); }, 0); a.then(function showB(b) { console.log(b); }); const d = function showD() { console.log('D'); }; d();
4。定義 d
const a = new Promise(function showA(resolve) { console.log('A'); resolve('B'); });
5。呼叫 d()
setTimeout(function showC() { console.log('C'); }, 0);
最終輸出順序:
a.then(function showB(b) { console.log(b); });
GIF供參考
互動範例
const d = function showD() { console.log('D'); };
再花點時間考慮輸出的順序。
✨你期望它是什麼? ✨
讓我們來解釋一下......
1。記錄「開始!」
d();
A D B C
3。承諾決議
console.log("Start!"); setTimeout(function showTimeout() { console.log("Timeout!"); }, 0); Promise.resolve("Promise!") .then(function showPromise(res) { console.log(res); }); console.log("End!");
4。記錄「結束!」
console.log("Start!");
最終輸出順序:
setTimeout(function showTimeout() { console.log("Timeout!"); }, 0);
GIF供參考
互動範例
本章並不太長,但我希望這些範例可以幫助您理解事件循環的工作原理。
我強烈建議嘗試互動頁面來分析其他範例。在該頁面上進行操作可以更輕鬆地理解正在運行的事件循環。
非常感謝大家對我之前貼文的喜愛!
下週見! ?
再見
以上是技術面試問題 - 部分事件循環的詳細內容。更多資訊請關注PHP中文網其他相關文章!