如何理解 JavaScript 中的事件循环(Event Loop)?

JavaScript employs a single-threaded execution model, leveraging the event loop to achieve asynchronous programming. The event loop coordinates the execution order of the call stack, macro task queue, and micro task queue, enabling non-blocking concurrent execution. The core workflow of the event loop is as follows: 1. **Synchronous Execution**: The browser main thread sequentially executes global synchronous code, pushing function calls into the call stack. 2. **Asynchronous Scheduling**: When asynchronous operations (e.g., `setTimeout`, `Promise.then`, `fetch`) are encountered, their callback functions are added to their respective queues. 3. **Task Scheduling**: When the call stack is empty, micro tasks are executed first, followed by macro tasks. 4. **Cycle Execution**: This process repeats until all tasks are completed. Key characteristics: - Micro tasks (e.g., `Promise.then`, `queueMicrotask`, `MutationObserver`) are prioritized over macro tasks (e.g., `setTimeout`, `setInterval`, I/O operations). - After each macro task completes, all micro tasks are immediately cleared and the next macro task is executed. Example analysis: ```javascript console.log('1'); setTimeout(() => console.log('2'), 0); Promise.resolve().then(() => console.log('3')); console.log('4'); ``` Output order: 1 → 4 → 3 → 2 Analysis: - '1' and '4' are synchronous code, executed first. - The `Promise.then` callback is added to the micro task queue and executed afterward. - The `setTimeout` callback is added to the macro task queue and executed later. - After the synchronous code completes, micro tasks (outputting '3') are processed before executing the macro task (outputting '2'). The event loop is the core mechanism of JavaScript's asynchronous programming model. Understanding its operation is critical for avoiding common pitfalls, such as timer delays and Promise execution timing.