JS Sketchbooksee JavaScript think ✏️
← back to the map
6

Time & Async

The big question: “The event loop, callbacks, promises, async/await”

but why do we need this?

Some things a program asks for are slow — fetching data across the internet takes an eternity in machine time. If JavaScript simply waited, the whole page would freeze with it: no clicks, no typing, no scrolling, until the data arrived. Async is how one worker stays responsive while slow things cook. And since every single Playwright command works this way, an automation tester lives and breathes this phase.

in plain words

JavaScript does exactly one thing at a time — it is single-threaded. Code that runs one step after another, each step waiting for the previous one, is called synchronous. That’s fine until one step is slow (like fetching data across the internet): synchronous waiting would block everything — frozen page, dead buttons.

The fix is to be asynchronous, or non-blocking: start the slow job, immediately move on, and get called back when the result is ready. Picture one waiter serving a whole café: they don’t stand at your table while the kitchen cooks (blocking); they take your order, serve others, and return when the bell rings (non-blocking). The bell system is JavaScript’s event loop.

This single idea is the heart of the browser AND of Node.js — and of every Playwright test you’ll ever write (they’re async from the first line). It’s also where the visualizations in this app do their finest work.

words you’ll own after this
single-threaded

JavaScript has one worker doing one thing at a time — one waiter for the whole café.

synchronous

Step-by-step: each instruction finishes completely before the next begins.

blocking

When a slow synchronous step makes everything else wait — the frozen-page feeling.

asynchronous / non-blocking

Start a slow job, keep working on other things, handle the result when it arrives.

event loop

The coordinator: watches for finished jobs and hands their results back to JavaScript the moment it’s free.

promise

A receipt for a result that isn’t ready yet: “your data is coming — here’s what to do when it arrives (or fails).”

async / await

A friendlier way to write promise code so it READS like step-by-step code, while staying non-blocking underneath.

after this phase, you can…
  • Explain synchronous vs asynchronous and blocking vs non-blocking with the waiter analogy
  • Predict the order console.log, setTimeout and promises print in — and why
  • Fetch real data from an internet API and handle failure gracefully
  • Explain why every Playwright test line has await in front of it
this phase’s lab — see it move

✏️ This phase’s interactive lab is still being drawn — it arrives together with the phase’s lessons.

the lessons
  1. 6.1
    Sync vs async

    One thread, one stack — blocking freezes everything. Async = schedule, never wait.

  2. 6.2
    The event loop

    Stack, Web APIs, queue, and the one rule — setTimeout(fn, 0) explained forever.

  3. 6.3
    Callbacks & callback hell

    Results arrive inside callbacks — and dependent steps stack the pyramid of doom.

  4. 6.4
    Promises

    A receipt with one flip: pending → fulfilled/rejected. Flat chains, one error drain.

  5. 6.5
    Microtasks vs macrotasks

    The express lane: promise reactions drain COMPLETELY before the next timer or click.

  6. 6.6
    async/await

    Pause one function, free the stack, resume via the express lane — try/catch returns.

  7. 6.7
    fetch & APIs

    Request out, response back: two awaits, the ok-guard, and the status-code map.

  8. 6.8
    Parallel & racing

    Start first, await together: all, allSettled, race, any — results in INPUT order.

  9. 6.9
    Checkpoint: the Pokédex fetcher

    loading → data | error → done — the whole async machine in one resilient flow.