Lab: the runtime capstone
Combine async/await, closures, classes, error handling, and fetch in one connected session.
- Write and chain async functions using async/await
- Use closures to create private state
- Handle fetch errors with try/catch and status checks
- Design a class with encapsulated state
Optional capstone lab. This session brings together the runtime module: the event loop, promises, closures, classes, error handling, and fetch. Three checkpoints that build on each other.
Warm-up — the event loop in one glance
Run this and predict the output before you see it. The order is the whole lesson:
Sync runs first, then microtasks (Promise callbacks), then the task queue (setTimeout). That ordering governs every async pattern you write.
Checkpoint 1 — counter closure
Write makeCounter(start) that returns an object with increment(),
decrement(), and value() methods. The internal count starts at start and
is completely private — no external code should be able to set it directly.
Write makeCounter(start) returning an object with increment(), decrement(), and value() methods. The count is private — only accessible through the methods.
const c = makeCounter(5); c.increment(); c.value() → 6Checkpoint 2 — async retry
Write withRetry(fn, times) that calls the async function fn up to times
attempts, returning the first successful result. If all attempts throw, re-throw
the last error.
Write async function withRetry(fn, times) that calls the async function fn up to times attempts. Return the first resolved value. If every attempt throws, re-throw the last error.
withRetry(unstableFetch, 3) → resolved value on first success, or throws after 3 failuresCheckpoint 3 — graceful fetch
Run this fetch that deliberately targets a non-existent endpoint. Then modify it so that: (a) network errors are caught and logged, and (b) non-2xx HTTP responses throw a readable error with the status code.
The pattern: always check res.ok before calling .json(). A 404 or 500 is a
successful HTTP exchange — fetch only rejects on network failure, not bad
status codes.
Done?
Three green checks means you own the JavaScript runtime: closures for private state, async/await for sequencing, and defensive fetch for production network calls. These three patterns appear in nearly every real JS codebase.