DEV Community

Cover image for JavaScript’s Most Misunderstood Feature: The Event Loop Isn’t What You Think
Jonathan Idioseph
Jonathan Idioseph

Posted on

JavaScript’s Most Misunderstood Feature: The Event Loop Isn’t What You Think

Demystifying async behavior so you can predict it, without memorizing diagrams.

1. Why this matters (in plain English)

The Problem That Made Me Google at 2 AM

I was building a dashboard in Next.js.
Everything worked… except my loading spinner.

It just froze.
No error, no crash, it just stopped spinning.

Turns out, I had no clue I’ve met the event loop, just… indirectly. This guide strips the jargon and gives you a mental model you’ll actually use.

2. Think of JavaScript as a Restaurant

  • Kitchen = Call Stack (where cooking happens)
  • Waiter = Event Loop (decides what order to serve next)
  • Two waiting lines:

    • Fast line = Promises (.then(), async/await) → “urgent orders”
    • Slow line = Timers (setTimeout, clicks, network) → “big meal orders”

3. The Secret Rule Nobody Told Me

Before serving any big orders, the waiter must finish all "urgent orders" first.

That’s why a Promise often runs before a setTimeout, even if the timeout is set to 0.

Example 1: Why setTimeout(0) still feels “late”

console.log("Start");

setTimeout(() => console.log("Timeout"), 0);

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

console.log("End");
Enter fullscreen mode Exit fullscreen mode

Output:

Start  
End  
Promise  
Timeout
Enter fullscreen mode Exit fullscreen mode

Why?

  • JavaScript finishes the current work (Start, End)
  • Runs Promises (urgent orders) → "Promise"
  • Then runs setTimeout (big orders) → "Timeout"

Example 2: The silent performance bug with async/await

Bad:

await task1();
await task2(); // Waits for task1 before even starting task2
Enter fullscreen mode Exit fullscreen mode

Better:

await Promise.all([task1(), task2()]); // Both start together
Enter fullscreen mode Exit fullscreen mode

If tasks don’t depend on each other, run them in parallel. Saves time.

4. How This Saved My Spinner

My “frozen” spinner was because I ran a heavy loop that never let the Event Loop breathe.

for (let i = 0; i < 1e9; i++) {} // freezes everything
Enter fullscreen mode Exit fullscreen mode

Fix: Break work into chunks so the UI gets a chance to update.

function doWorkInChunks() {
  let i = 0;
  function chunk() {
    for (let j = 0; j < 100000; j++) i++;
    if (i < 1e9) setTimeout(chunk); // let UI breathe
  }
  chunk();
}
Enter fullscreen mode Exit fullscreen mode

5. Why You Should Care

Understanding the Event Loop means:

  • Faster apps
  • Less “freezing” UIs
  • Predictable async behavior

Even if you’re not “deep into backend stuff,” this is frontend survival skill.

6. Myths vs Reality (quick de-mystification)

  • Myth: setTimeout(fn, 0) runs immediately. Reality: It waits until all microtasks finish.
  • Myth: async/await is always faster than Promises. Reality: It’s about ordering. Sequential await can be slower than Promise.all.
  • Myth: The event loop is “browser stuff only.” Reality: Node.js has the loop too (with its own task sources); the microtask > macrotask rule still applies.

7. When to care (and when not to)

  • Care when: spinners freeze, progress bars stutter, “0ms” timers feel late, await feels slow.
  • Don’t overthink it when: the page is simple and nothing is heavy—ship it.

8. Debug checklist you can copy

  • Is something “late”? → Check for a Promise running first.
  • Is something “slow”? → Run independent tasks in parallel with Promise.all.
  • Is UI freezing? → Break big loops with setTimeout/requestIdleCallback.
  • Still weird? → Log order: console.log("A"), Promise .then("B"), setTimeout("C", 0).

9. Too Long; Didn't Read (stick this in your notes)

1). Sync finishes → 2) All microtasks run → 3) One macrotask runs → repeat.
Use Promise.all for parallel work; slice heavy loops so the UI can breathe.

Your turn: Ever had a bug that only happened because of “JavaScript timing magic”? Drop it in the comments, I might try to explain it in plain English.

Top comments (1)