Promises

The Course
•
4 min read

A promise represents an eventual outcome

A Promise is an object representing a value that may be available later. It starts pending, then settles once: fulfilled with a value or rejected with a reason. Settling does not mean the result is automatically printed or stored where you wanted it. Code must handle the outcome.

Promise.resolve(value) makes an already-fulfilled promise. .then(onSuccess) registers a callback and returns a new promise. The callback’s return becomes the next promise’s fulfillment value. .catch(onFailure) handles a rejection; returning an ordinary value from catch recovers the chain. Throwing keeps it rejected.

A then callback runs after the current synchronous work, even for an already-fulfilled promise. Do not read the result immediately after registering a callback and assume it has arrived. Trace what executes now versus what is scheduled for later.

The first examples observe completion using then and catch callbacks. These introductory editors wait for the promise produced by the final chain, so keep that chain as the last statement. The next lesson introduces a main entry point to make this ownership easier to see. Keep the last step as part of the chain, rather than starting unrelated work and assuming the value is ready. In the next lesson, async and await give another way to express those steps.

Predict and trace

Write the output before running. Follow the values through each call; if your prediction differs, identify the first step that surprised you.

Predict, then run JavaScript
const chain = Promise.resolve(20).then(value => value + 5);

console.log("Registered");
chain.then(value => {
  console.log(value);
  console.log("Finished");
});
Check your prediction
Registered
25
Finished

The chain is built first. Registered prints before the scheduled callbacks. Finished is inside the success callback, so it follows the value.

Recover or propagate?

A catch callback that returns text recovers to a fulfilled promise. A later then can use that text. Contrast this with throwing from catch, which keeps the chain rejected. Predict which callbacks run before trying the code.

Recover or propagate? JavaScript
const recovered = Promise.resolve("Notes")
  .then(() => {
    throw new Error("Unavailable");
  })
  .then(() => "This is skipped")
  .catch(error => `Fallback: ${error.message}`);

recovered.then(value => {
  console.log(value);
});
Check your prediction
Fallback: Unavailable

The error skips the next success callback. The final catch supplies a documented fallback value. A fallback should be intentional rather than an empty value that disguises failure.

Build it yourself

Exercise

Promises: practise

Build a chain starting from Promise.resolve(” Notes ”). Trim the text, convert it to uppercase, and print it in the final then callback.

Your working space JavaScript
// Each then callback should return the next value.
Hint 1: the idea

A missing return changes the next value to undefined.

Hint 2: a first step

Return trim’s result from one callback and uppercase from the next.

Show one solution
Promise.resolve("  Notes  ")
  .then(text => text.trim())
  .then(text => text.toUpperCase())
  .then(text => {
    console.log(text);
  });
NOTES

Temporarily use a block body without return in the first transformation. Observe the failure, then restore it. The next callback cannot uppercase undefined.

Test a changed requirement

Temporarily use a block body without return in the first transformation. Observe the failure, then restore it. The next callback cannot uppercase undefined.

Explain before moving on

What does then return? Why does an already-fulfilled promise still not run its callback inline?

Going further

Read MDN’s guide to using promises after working through the examples. Use it as a reference when you meet an unfamiliar option; finishing every reference section is not required for this course.

Was this article helpful?

Your response is saved on this device.