Modern JavaScript: Async, Fetch & APIs

Lesson 4 of 18

What a promise is

A promise is a modern object representing a value that will be available in the future — the result of an async operation. Promises solve callback hell by giving async operations a clean, chainable, standardized shape. They're the foundation of modern async JavaScript (and fetch returns one), so understanding them is essential.

A promise represents a future result

A promise is an object that stands for a value not available yet but that will be (or will fail). Think of it as a receipt: "I promise to give you the result when it's ready." A promise is in one of three states:

  • pending — the operation is still in progress (no result yet).
  • fulfilled — it succeeded, and the promise has a result value.
  • rejected — it failed, and the promise has an error.

A pending promise eventually settles into either fulfilled (success) or rejected (failure). You attach handlers to say "when it fulfills, do this; if it rejects, do that."

Using a promise with .then

Try it Yourself
Loading editor…
Result

promise.then(callback) says "when this promise fulfills, run this function with the result." The .then callback runs later, when the async work finishes. Unlike a raw callback, this reads more cleanly — and, crucially, promises can be chained (next lessons), which is what defeats callback hell. Most modern async APIs (including fetch) return promises for you to .then.

Creating a promise (to understand them)

You usually consume promises from APIs rather than create them, but making one shows how they work:

Try it Yourself
Loading editor…
Result

Inside new Promise((resolve, reject) => ...), you call resolve(value) on success or reject(error) on failure. Whoever holds the promise uses .then for the result. Now fetchUser returns something (a promise) instead of burying the result in a callback — a big improvement, and the key to chaining.

Why promises are better than callbacks

Promises fix callbacks' core problems:

  • They're returnable — a function can return a promise, so you can pass async results around (unlike callbacks buried inside).
  • They chain.then returns a new promise, so sequential steps flatten into a readable chain (no pyramid — next lesson).
  • Unified errors — one .catch handles errors for a whole chain (no duplicated checks).
  • Standardized — a consistent shape across all modern async APIs.

This is why modern JavaScript is built on promises, and why async/await (a nicer syntax on top of promises) is the standard. Master promises and the rest follows.

The mistake beginners make

Thinking a promise is the value — trying to use the result directly (var user = fetchUser(1); print(user.name)) when fetchUser returns a promise, not the user. The value is still in the future; you access it via .then (or await, later). Also, confusing the three states or forgetting a promise settles only once. Remember: a promise is a placeholder for a future result — use .then to get that result when it's ready, not the promise object itself.

Your turn

Try it Yourself
Loading editor…
Result

Your turn

  1. Understand a promise as an object representing a future result of an async operation.
  2. Know the three states: pending, then either fulfilled (with a value) or rejected (with an error).
  3. Use .then(callback) to handle a fulfilled result, and see promises are returnable (unlike buried callbacks).

Key points

  • A promise is an object representing a value that will be available in the future (the result of async work).
  • It has three states: pending -> fulfilled (success, with a value) or rejected (failure, with an error).
  • Use promise.then(callback) to handle the result when it fulfills; fetch and modern APIs RETURN promises.
  • Promises beat callbacks: they're returnable, they chain (flattening sequences), and have unified error handling.

Q&A · 0

Enrol to ask questions and join the discussion.

No questions yet — be the first to ask.