Represent a Future Result

Represent a Future Result

A promise represents an eventual fulfillment value or rejection reason. then schedules its handler after the current synchronous work; returning a value from a handler passes it to the next link.

Before this topic, review Pass an Operation to Another Function if its terms are unfamiliar.

What you’ll learn

  • Explain represent a future result through the school example.
  • Trace the shown operations and distinguish their result from displayed output.
  • Make the practice change and explain its consequence: The promise value changes, while synchronous Start and End still precede its handler.

Work through the school example

This is JavaScript using language features and the host console. Read the initial values, then follow each operation to its displayed result. A declaration names a value, a function call performs an operation, and console.log displays its arguments.

JavaScript · school.js · complete example

console.log("Start");
Promise.resolve(72).then((mark) => console.log(mark));
console.log("End");

Expected output

Start
End
72
Run in JavaScript compiler →

Introduction to Promises

JavaScript Promises are a powerful way to handle asynchronous operations like network requests, timers, or file access. A Promise represents a value that may be available now, later, or never.

Creating a Promise

A Promise is created using the Promise constructor, which takes a function with two arguments: resolve and reject.

const fetchData = () => {
  return new Promise((resolve, reject) => {
    let success = true;
    setTimeout(() => {
      if (success) {
        resolve("Data fetched successfully!");
      } else {
        reject("Failed to fetch data.");
      }
    }, 1000);
};

fetchData()
  .then((data) => console.log(data))
  .catch((error) => console.error(error));
Data fetched successfully!

Understanding the Output

In the above example, we used setTimeout to simulate an asynchronous operation. If success is true, the promise is resolved. Otherwise, it's rejected. The .then() method handles the success case, and .catch() handles errors.

Why use Promises?

Without Promises, asynchronous code becomes hard to manage, especially when nested. Promises help avoid callback hell by providing a cleaner and more readable way to handle async operations.

Chaining Promises

One of the main strengths of Promises is chaining. You can return values from a .then() block and pass it to the next .then().

const stepOne = () => {
  return new Promise((resolve) => {
    setTimeout(() => resolve("Step 1 complete"), 1000);
  });
};

const stepTwo = (message) => {
  console.log(message);
  return new Promise((resolve) => {
    setTimeout(() => resolve("Step 2 complete"), 1000);
  });
};

const stepThree = (message) => {
  console.log(message);
  return new Promise((resolve) => {
    setTimeout(() => resolve("Step 3 complete"), 1000);
  });
};

stepOne()
  .then(stepTwo)
  .then(stepThree)
  .then((finalMessage) => console.log(finalMessage));
Step 1 complete
Step 2 complete
Step 3 complete

Explanation

Each function returns a Promise. As each Promise resolves, the next one in the chain is called. This pattern is great for running asynchronous tasks in sequence.

What happens if something fails in the chain?

If a Promise in the chain is rejected, the control jumps to the nearest .catch() block.

const faultyStep = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => reject("Something went wrong!"), 1000);
  });
};

stepOne()
  .then(faultyStep)
  .then(stepThree)
  .catch((error) => console.error("Error caught:", error));
Step 1 complete
Error caught: Something went wrong!

Questions to Develop Intuition

Q1: What happens if you forget to return a Promise in a .then()?

A: The next .then() in the chain receives undefined. This can lead to bugs if you're expecting a value or further async operation.

Q2: Can you chain a .catch() after a .then()?

A: Yes. If any previous Promise is rejected, the .catch() block handles the error.

Q3: Is it mandatory to use catch() at the end of a chain?

A: It's not mandatory, but it's good practice to avoid unhandled Promise rejections.

Summary

  • A Promise is an object that represents a future value.
  • .then() is used to handle resolved values, .catch() for errors.
  • Chaining allows running async tasks sequentially in a readable way.
  • Always return Promises when chaining to avoid unexpected behavior.

Recognize the important boundary

A promise is not the result itself. Return nested promises to preserve sequencing, and handle rejection rather than leaving failures unobserved.

Compare the demonstrated ordering with the event loop and promise-handler walkthrough.

Try a small variation

JavaScript · original source for practice

console.log("Start");
Promise.resolve(72).then((mark) => console.log(mark));
console.log("End");

Your task: Replace resolve(72) with resolve(80). Predict the result before running the edited program.

The source is repeated here. If the edit targets the HTML rather than the script, use the markup repeated below; the worked answer also repeats the changed markup.

Worked answer and reasoning

The promise value changes, while synchronous Start and End still precede its handler.

JavaScript · complete worked variation

console.log("Start");
Promise.resolve(80).then((mark) => console.log(mark));
console.log("End");

Expected output

Start
End
80
Run in JavaScript compiler →

Predict the original program

JavaScript · original program for this question

console.log("Start");
Promise.resolve(72).then((mark) => console.log(mark));
console.log("End");
What does the original JavaScript program display, in order?
Choose one answer. You can try again.

Answer and explanation

Start → End → 72

A promise represents an eventual fulfillment value or rejection reason. then schedules its handler after the current synchronous work; returning a value from a handler passes it to the next link. A promise is not the result itself. Return nested promises to preserve sequencing, and handle rejection rather than leaving failures unobserved.

Keep the useful idea

A promise represents an eventual fulfillment value or rejection reason. then schedules its handler after the current synchronous work; returning a value from a handler passes it to the next link.

Check your variation against this explanation: The promise value changes, while synchronous Start and End still precede its handler.

Use the JavaScript array reference library for individual array operations and boundary tests to check a rule independently.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Read an Asynchronous Sequence →