JavaScript 中的事件循环(Event Loop)是如何工作的?

JavaScript's event loop mechanism is the core principle for implementing asynchronous programming. Its working mechanism is as follows: **Basic Working Flow:** 1. **Synchronous Execution:** The browser's main thread (Call Stack) sequentially executes synchronous code (e.g., `console.log`). Execution results are pushed into the call stack. 2. **Asynchronous Task Hierarchies:** When asynchronous operations (e.g., `setTimeout`, `Promise`, `fetch`) are encountered, their callback functions are added to corresponding task queues: - **Macro Task Queue (MacroTask):** Contains `setTimeout`, `setInterval`, I/O operations, and UI rendering, which must be executed when the call stack is idle. - **Micro Task Queue (MicroTask):** Includes `Promise.then/catch/finally`, `queueMicrotask`, and `MutationObserver`, which execute before macro tasks. 3. **Task Scheduling:** When the call stack is empty, the event loop first clears the microtask queue (executing callbacks in order), followed by executing the first task from the macro task queue. 4. **Cycle Execution:** The above process repeats until all tasks are completed. **Example Code:** ```js console.log('1'); setTimeout(() => { console.log('2'); }, 0); Promise.resolve().then(() => { console.log('3'); }); console.log('4'); ``` **Output Order:** 1 → 4 → 3 → 2 **Analysis:** - Synchronous code (`console.log('1')` and `console.log('4')`) executes immediately. - `Promise.then` belongs to the microtask queue and runs immediately after the current macro task completes. - `setTimeout` is a macro task that must be executed in the next event loop cycle. **Importance of Understanding Event Loop:** Understanding the event loop's mechanism is crucial for mastering asynchronous programming patterns, optimizing performance, and debugging complex asynchronous logic. **Revised Paragraph:** JavaScript's event loop mechanism is the core principle for implementing asynchronous programming. Its working mechanism is as follows: **Basic Working Flow:** 1. **Synchronous Execution:** The browser's main thread (Call Stack) sequentially executes synchronous code (e.g., `console.log`). Execution results are pushed into the call stack. 2. **Asynchronous Task Hierarchies:** When asynchronous operations (e.g., `setTimeout`, `Promise`, `fetch`) are encountered, their callback functions are added to corresponding task queues: - **Macro Task Queue (MacroTask):** Contains `setTimeout`, `setInterval`, I/O operations, and UI rendering, which must be executed when the call stack is idle. - **Micro Task Queue (MicroTask):** Includes `Promise.then/catch/finally`, `queueMicrotask`, and `MutationObserver`, which execute before macro tasks. 3. **Task Scheduling:** When the call stack is empty, the event loop first clears the microtask queue (executing callbacks in order), followed by executing the first task from the macro task queue. 4. **Cycle Execution:** The above process repeats until all tasks are completed. **Example Code:** ```js console.log('1'); setTimeout(() => { console.log('2'); }, 0); Promise.resolve().then(() => { console.log('3'); }); console.log('4'); ``` **Output Order:** 1 → 4 → 3 → 2 **Analysis:** - Synchronous code (`console.log('1')` and `console.log('4')`) executes immediately. - `Promise.then` belongs to the microtask queue and runs immediately after the current macro task completes. - `setTimeout` is a macro task that must be executed in the next event loop cycle. **Importance of Understanding Event Loop:** Understanding the event loop's mechanism is crucial for mastering asynchronous programming patterns, optimizing performance, and debugging complex asynchronous logic.