Manuals / JavaScript / Ch 11

E · Deep JSAdvanced55 min read

11. Event loop, closures & this

JavaScript · 56 pages source format

The event loop processes call stack, microtasks (Promises), and macrotasks (setTimeout) in a specific order — interview gold. Closures capture outer variables. this binding depends on call site (arrow functions inherit lexical this). These models explain flaky tests and framework behavior.

What you'll learn

  • Call stack & task queues
  • Microtasks vs macrotasks
  • Closures in practice
  • this binding rules
  • Common interview snippets

Event loop order

Run sync code first. Drain all microtasks (Promise callbacks). Then one macrotask (setTimeout). Repeat. That is why Promise.then runs before setTimeout(0).

console.log("1 sync")
setTimeout(() => console.log("2 macrotask"), 0)
Promise.resolve().then(() => console.log("3 microtask"))
console.log("4 sync")
// Output: 1, 4, 3, 2

Do this now

Predict output, then run: console.log(1); setTimeout(()=>console.log(2)); Promise.resolve().then(()=>console.log(3)); console.log(4).

Clear?

Three more snippets

Practice until predictions are reliable. Draw the queue on paper if needed.

  • Nested setTimeout + Promise chains
  • async function with await vs bare Promise.then
  • Multiple Promise.then in sequence

Do this now

Run 3 async snippets from javascript.info or Lydia Hallie's visual. Write predicted vs actual in notes.

Clear?

Closures

Inner function closes over outer variables even after outer returns. Classic: loop with var + setTimeout bug; fix with let or IIFE.

function createCounter() {
  let count = 0
  return {
    increment: () => ++count,
    getCount: () => count,
  }
}

Do this now

Write createCounter() returning {increment, getCount} using closure. Count is private.

Clear?

this binding

Regular function: this = call site (obj.method()). Arrow function: this = enclosing lexical scope. bind/call/apply override.

Do this now

Demonstrate obj.getName() vs const fn = obj.getName; fn() losing this. Fix with arrow method or bind.

Clear?

Why tests flake

Missing await, race between assertion and microtask, setTimeout without waiting. Event loop literacy prevents automation pain.

Do this now

Write a flaky-looking test that fails without await and passes with it. Comment why.

Clear?

Checklist

Chapter videos

JSConf / Philip Roberts

What the heck is the event loop?

Why your awaits (and flaky waits) behave that way.

Open on YouTube →