Async JavaScript

Event Loop, Microtasks & Macrotasks

JavaScript executes synchronous code on a call stack and uses an event loop to resume queued work later. Promise reactions run as microtasks, which are drained before the next task such as a timer or event callback.
  • JavaScript execution is run-to-completion
  • The call stack must empty before queued work runs
  • Microtasks run before the next task
  • Long synchronous work blocks everything
  • Node and browsers have host-specific details
One event-loop turn
Microtasks run after the current stack, before the next task.
Ordering example
console.log("A")

setTimeout(() => console.log("timer"), 0)

Promise.resolve().then(() => console.log("promise"))

console.log("B")

// A
// B
// promise
// timer
The Promise reaction is a microtask; the timer callback is a later task.
Queues and work
ThingExamplesWhen it runs
Call stackCurrent synchronous functionImmediately
MicrotaskPromise reactions, queueMicrotaskAfter stack clears, before next task
TaskTimers, events, I/O callbacksOne per event-loop turn
RenderingBrowser paint/layoutBetween turns, host-specific
Sources
  • MDN JavaScript Guide and ReferencePromises timing and async behavior
  • Node.js Documentation and Learn Node.jsThe Node.js Event Loop
  • The Modern JavaScript TutorialEvent loop