JavaScript Runtime8h estimated

Promises & Async/Await

Difficulty
Importance

The problem

Coordinating multiple asynchronous operations with raw callbacks quickly becomes an unreadable, deeply nested mess ('callback hell'), and there's no clean way to express 'wait for this, then do that' or to propagate an error from deep inside a chain of async steps.

Why now

The event loop explained that async results arrive via the callback queue, but not how to compose them cleanly. Promises are a higher-order abstraction over that raw callback mechanism — and higher-order-functions already established the value of naming and reusing a pattern instead of hand-writing it every time.

Mental model

A promise is a placeholder for a value that doesn't exist yet, in one of three states: pending, fulfilled, or rejected — once it settles, it stays settled forever. async/await is syntax that makes code reading like synchronous code while it's secretly still using the event loop underneath: await pauses the async function (not the whole runtime) until the promise settles, then resumes with the result or throws the error.

Requires

Unlocks

Used in

Projects

  • Rewrite a callback-based function (e.g. a fake delayed API call) using Promises, then again using async/await, comparing readability
  • Use Promise.all to fetch three resources concurrently and measure the time savings versus awaiting them one at a time

Examples

  • const data = await fetch(url).then(r => r.json()); reads top-to-bottom despite being fully asynchronous underneath
  • Promise.all([a, b, c]) runs three async operations concurrently and resolves once all three finish, rather than one after another

Resources

Mastery checklist