Skip to content
SunnyWriteUps
Go back

Demystifying the JavaScript Event Loop, Microtasks, and Timers

Edit page

Here is a breakdown of how JavaScript handles asynchronous operations under the hood.


The Core Actors

The Event Loop is a continuous process that moves callbacks between four main areas:

  1. The Call Stack: Where your synchronous JavaScript code executes. Functions are pushed onto the stack when called and popped off when they return.
  2. Web APIs / Node APIs: Features provided by the browser (like the DOM or fetch) or Node.js (like fs or crypto) that run tasks in the background.
  3. The Microtask Queue: A high-priority queue for critical, immediate follow-up work.
  4. The Macrotask Queue (Task Queue): A lower-priority queue for deferred work like timers and UI events.

Microtasks vs. Macrotasks

The most common source of asynchronous bugs is misunderstanding the priority difference between these two queues.

Whenever the Call Stack empties, the Event Loop follows a strict rule: Drain the Microtask Queue completely before touching the Macrotask Queue.

The Reality of Timers

A common misconception is that setTimeout(callback, 1000) guarantees the callback will run exactly 1,000 milliseconds from now.

In reality, timers dictate the minimum delay. After 1,000ms, the Web API pushes your callback into the Macrotask Queue. However, if the Call Stack is busy, or if the Microtask Queue is flooded with Promises, your timer callback has to wait in line. This is why setTimeout(..., 0) doesn’t execute instantly—it simply queues the task to run at the next available opportunity.

Modern Async Patterns

Today, async and await are the standard patterns for handling asynchronous code, providing a cleaner alternative to nested Promise chains (the infamous “callback hell”).

Under the hood, async/await is syntactic sugar over Promises. When the engine encounters an await keyword, it suspends the execution of that specific function and yields control back to the main thread. The remainder of the function is then scheduled as a Microtask to be executed once the awaited Promise resolves.


Edit page
Share this post on:

Previous Post
Getting Started Building Reactive 3D Scenes for Production
Next Post
Building Browser-Based Media Tools The Power of Canvas and WebAssembly