Promises in JavaScript
Creating and Chaining



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));
    

Output:

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));
    

Output:

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));
    

Output:

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



Welcome to ProgramGuru

Sign up to start your journey with us

Support ProgramGuru.org

You can support this website with a contribution of your choice.

When making a contribution, mention your name, and programguru.org in the message. Your name shall be displayed in the sponsors list.

PayPal

UPI

PhonePe QR

MALLIKARJUNA M