Mastering JavaScript Event Loop: Threads, Tasks, and Execution Flow
This article explains JavaScript's single‑threaded nature, the various browser threads, how the event loop coordinates synchronous and asynchronous tasks, the roles of macro‑ and micro‑task queues, and how the execution stack processes them to achieve non‑blocking behavior.
Introduction
JavaScript is a single‑threaded, non‑blocking scripting language. Because there is only one main thread, JavaScript cannot perform true multithreading, but it relies heavily on asynchronous concepts managed by the Event Loop.
JS Threads
JS Engine Thread (Main Thread): Parses and executes JavaScript code.
GUI Rendering Thread: Renders the browser UI, parses HTML/CSS, builds the DOM and render trees, and performs layout and painting. It runs when the page needs repaint or reflow.
Timer Thread (setTimeout): Counts time independently of the main thread and, when the timer expires, pushes the callback into the event queue.
HTTP Request Thread (ajax): Sends XMLHttpRequest in a separate thread; when the response arrives, the callback is placed into the event queue.
Browser Event Thread (onclick): Listens for DOM events; when an event occurs, its callback is added to the event queue.
Mutual Exclusion of Main and Rendering Threads: While the JS engine runs, the rendering thread is paused; pending UI updates wait until the engine becomes idle.
Event Loop Polling Thread
The Event Loop acts as a mediator between the main thread, asynchronous threads, and the message queue, continuously looping. It only checks the queue for pending tasks after the main thread finishes all synchronous code.
Synchronous vs Asynchronous Tasks
Synchronous tasks execute immediately (e.g., a simple function call). Asynchronous tasks include AJAX requests, promises, or timers, which are placed into the event queue.
Task Queue (Event Queue)
The task queue is a FIFO structure that stores pending tasks. Synchronous tasks run right away on the main thread, while asynchronous tasks wait in the queue until the main thread is idle.
Macro‑Task and Micro‑Task Queues
Macro‑Task (MacroTask): Includes script execution, UI rendering, setTimeout, setInterval, and setImmediate (Node.js).
Micro‑Task (MicroTask): Includes Promise callbacks such as then(), catch(), and finally().
Differences: There can be multiple macro‑task queues, but only one micro‑task queue. Micro‑tasks are processed before the next macro‑task.
Execution Stack
Both macro‑tasks and micro‑tasks are pushed onto the call stack. JavaScript has a single call stack; each function call creates a new execution context that is pushed onto the stack and popped when the function returns.
Summary
Synchronous tasks run first, while asynchronous tasks are placed into the event loop. Within the loop, micro‑tasks execute before macro‑tasks. This cycle repeats, forming the JavaScript Event Loop, which is essential for understanding execution order and writing reliable asynchronous code.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
NetEase Smart Enterprise Tech+
Get cutting-edge insights from NetEase's CTO, access the most valuable tech knowledge, and learn NetEase's latest best practices. NetEase Smart Enterprise Tech+ helps you grow from a thinker into a tech expert.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
