JavaScript Promises & Async/Await Simulator
Visualize JavaScript promises, async/await, microtasks, task queues, setTimeout ordering, rejection handling, and Promise.all with an interactive event-loop simulator inspired by classic JavaScript visual guides.
Category: Programming
Topics covered: javascript, promises, async-await, event-loop, microtasks, settimeout, nodejs, programming, frontend, backend, educational, interactive
// simulator
JavaScript Promises & Async/Await Simulator
Visualize JavaScript promises, async/await, microtasks, task queues, setTimeout ordering, rejection handling, and Promise.all with an interactive event-loop simulator inspired by classic JavaScript visual guides.
// event loop lab
Start in global execution
The script begins on the call stack. Nothing async has been scheduled yet.
Runtime state
Read the phase rail first, then inspect the boxes below for what changed.
Normal code runs first.
Timers wait outside JS.
Promise state changes.
Promise callbacks run next.
Timers run after microtasks.
Logs appear in order.
What gets printed first after Start?
About this JavaScript async simulator
What you'll learn
- Why synchronous code runs before promise callbacks and timers
- How fulfilled, rejected, and pending promise states affect handler execution
- Why promise callbacks are microtasks, while timers are tasks
- How async functions run until await and then resume later
- How catch and finally behave after a promise rejection
- How Promise.all waits for several async operations at once
Visual model covered
- Call stack: currently executing synchronous JavaScript
- Runtime APIs: timers, network work, and other browser or runtime-owned async work
- Microtask queue: promise handlers, queueMicrotask callbacks, and async function continuations
- Task queue: timer and event callbacks that run after microtasks drain
Inspired by a classic visual guide
This simulator is an original interactive companion inspired by Lydia Hallie's popular JavaScript visualized article on promises and async/await. It uses its own diagrams and step logic while covering the same core mental models.
Browser-safe by design
The simulator does not execute arbitrary JavaScript. Each scenario is modeled as a deterministic event-loop trace so learners can step backward, make predictions, and see exactly why the output order changes.
Overview
JavaScript runs on one thread, so async code is about the order in which callbacks get their turn. This simulator makes that order visible. It shows the call stack, the runtime where timers wait, the promises, the microtask queue, the task queue and the console, and steps through short programs one action at a time. The first scenario shows why microtasks beat timers: a promise callback runs before a setTimeout callback with a zero delay, because the microtask queue drains completely before the next task starts. The second shows what await really does: the async function runs synchronously until the first await, then pauses while the outer script keeps going, and resumes later as a microtask. The third follows a rejected promise as it skips to catch while synchronous code still runs, with finally running for cleanup. The last shows Promise.all waiting for every input before it resolves. Once you can predict the console output, async bugs such as unexpected ordering become much easier to reason about.
Try this
- Step through "Microtasks beat timers" and predict the console order before each step.
- Play "Await suspends the function" and watch run() pause at await while the outer script keeps logging.
- Open "Rejections jump to catch" to see the rejection skip ahead to catch and finally run last.
Frequently asked questions
- Why does a promise callback run before setTimeout with 0 ms?
- Promise callbacks are microtasks, and the event loop drains the whole microtask queue before it takes the next task. setTimeout callbacks are tasks, so they wait until the microtasks are done.
- Does await block the thread?
- No. await pauses only the async function it is in. The rest of the program keeps running, and the function resumes as a microtask when the awaited promise settles.
- What happens if one promise in Promise.all rejects?
- Promise.all rejects immediately with that reason and ignores the results of the others. Use Promise.allSettled when you need every result regardless of failures.
Try next
// simulator
Preview Environment Simulator
See how a pull request becomes a temporary copy of your app, complete with a private URL, safe test data, review checks, and automatic cleanup.
// game
Heroku-Style Name Generator
Generate names the way Heroku, Docker, Kubernetes, and petname do, see how the word lists combine, and learn when the birthday problem makes random names collide.
// simulator
Log Aggregation Pipeline Simulator
Follow production logs from applications through collection, parsing, filtering, buffering, sharded indexing, and search. Trigger traffic spikes, parser failures, and slow indexing to see where backpressure builds and logs can be lost.