Web 瀏覽器中的事件迴圈
絕大多數現代 JavaScript 環境都根據事件迴圈工作。這是計算機程式設計中的一個常見概念,這實際上意味著你的程式不斷地等待新事物發生,並且當它們發生時,會對它們做出反應。在主機環境呼叫到你的程式,在產卵事件迴圈,然後一個轉或嘀或任務 執行完成。當轉彎完成後,主機環境會在所有這一切開始之前等待其他事情發生。
一個簡單的例子就是在瀏覽器中。請考慮以下示例:
<!DOCTYPE html>
<title>Event loop example</title>
<script>
console.log("this a script entry point");
document.body.onclick = () => {
console.log("onclick");
};
setTimeout(() => {
console.log("setTimeout callback log 1");
console.log("setTimeout callback log 2");
}, 100);
</script>
在此示例中,主機環境是 Web 瀏覽器。
- HTML 解析器將首先執行
<script>
。它將執行完成。 - 對
setTimeout
的呼叫告訴瀏覽器,在 100 毫秒之後,它應該將任務排隊以執行給定的操作。 - 與此同時,事件迴圈負責不斷檢查是否還有其他事情要做:例如,渲染網頁。
- 在 100 毫秒之後,如果事件迴圈由於某些其他原因而不忙,它將看到
setTimeout
排隊的任務,並執行該函式,記錄這兩個語句。 - 在任何時候,如果有人點選了正文,瀏覽器會將任務釋出到事件迴圈以執行點選處理函式。事件迴圈,因為它不斷檢查要做什麼,將看到這一點,並執行該功能。
你可以看到在此示例中,如何在 JavaScript 程式碼中有幾種不同型別的入口點,事件迴圈呼叫它們:
<script>
元素立即被呼叫setTimeout
任務將釋出到事件迴圈並執行一次- 點選處理程式任務可以多次釋出並每次執行
事件迴圈的每一輪都有很多東西; 只有部分人會呼叫這些 JavaScript 任務。有關完整詳細資訊,請參閱 HTML 規範
最後一件事:我們說每個事件迴圈任務執行完成是什麼意思?我們的意思是通常不可能中斷排隊等待作為任務執行的程式碼塊,並且永遠不可能執行與另一個程式碼塊交錯的程式碼。例如,即使你在完美時間點選,也無法獲得上述程式碼來記錄兩個 setTimeout callback log 1/2"
之間的 onclick
。這是由於任務釋出的工作方式; 它是合作的和基於佇列的,而不是先發制人的。