PProtokol
Async JavaScript & APIs/Why Async Exists: The Event Loop in Plain English
outline — lesson 1 of 9

Level 1 · Complete beginner · 12 min

Why Async Exists: The Event Loop in Plain English

Learn why JS does not "freeze" while waiting for slow things, using the event loop.

What you will learn

  • Explain why JavaScript is single-threaded
  • Describe what would happen if slow operations blocked the whole program
  • Explain the call stack, task queue, and event loop at a high level
  • Predict the order code runs in when timers and synchronous code mix

The idea

JavaScript runs your code one line at a time, on a single thread. It cannot do two things at the exact same instant. But it can PAUSE a slow operation, keep doing other work, and come back later when the slow thing is ready.

Why does this matter?

Web pages need to stay responsive: scrolling, clicking, typing must keep working while the browser waits for a network request, a timer, or a file to load. If JS blocked on every slow operation, the whole page would freeze until it finished.

A real-world analogy

Imagine a single chef in a kitchen. Instead of standing and staring at the oven for 20 minutes waiting for bread to bake, the chef sets a timer, starts chopping vegetables for the next dish, and only goes back to the oven when the timer rings. One chef, but nothing sits idle.

See it in code

Synchronous code runs top to bottom, in order
console.log("1: start");
console.log("2: middle");
console.log("3: end");
// Output: 1: start, 2: middle, 3: end -- always, every time

See it in code

Async code lets slow work happen later, without blocking
console.log("1: start");

setTimeout(() => {
  console.log("2: this runs later");
}, 0);

console.log("3: end");
// Output: 1: start, 3: end, 2: this runs later

Line by line

  • console.log("1: start");

    Runs immediately -- it is on the main call stack.

  • setTimeout(() => {...}, 0);

    Hands the callback to the browser/runtime to run later, even with a delay of 0ms. JS does NOT wait here.

  • console.log("3: end");

    Runs right after the setTimeout call returns, because setTimeout does not block.

  • (callback runs)

    Only after ALL synchronous code has finished does the event loop pull the callback off the queue and run it.

What do you think happens?

What order do the three console.log lines print in the second code example above?

Have a guess before you read on. Guessing wrong is part of learning it.

Try it yourself

Predict the console.log order for this snippet before running it in your head: console.log("A"); setTimeout(() => console.log("B"), 0); console.log("C"); setTimeout(() => console.log("D"), 0);

Worth knowing

Common mistake: thinking setTimeout(fn, 0) runs immediately. It never does -- 0ms just means "as soon as possible after the current code finishes," not "right now." Also, JS itself is single-threaded, but the browser provides separate mechanisms (timers, network) that run outside your code and hand results back via the event loop.

The proper words for it

Call stack
The list of function calls JS is currently working through, one at a time, top to bottom.
Event loop
The mechanism that checks: is the call stack empty? If so, take the next waiting callback and run it.
Task queue
A waiting line of callbacks (from timers, network, etc.) ready to run once the stack is clear.
Single-threaded
JS can only execute one piece of code at a time -- no true parallel execution of your JS.

Where you'll meet this

Every time a web page loads data without freezing the scroll bar, or a chat app receives a message while you keep typing, the event loop is what makes that possible. Node.js servers use the same model to handle many users at once without one slow request blocking everyone else.

Lesson recap

  • JS runs one line at a time on a single thread
  • Slow operations are handed off and their callbacks run later
  • The event loop only runs a queued callback once the call stack is empty
  • setTimeout(fn, 0) still waits for all current synchronous code to finish first

Still fuzzy on any of this?

That's normal, and it's not a dead end. Pick a different way to hear it.

Quick check

1. Why can't JavaScript just block and wait for a slow network request?

2. When does the event loop run a queued callback (like from setTimeout)?

3. What does setTimeout(fn, 0) actually guarantee?

First, pass the quick check to unlock "Callbacks and Callback Hell".

Your tutor

patient by design

No question is too basic here. Ask anything — I'll explain it in plain words and guide you rather than handing over answers.