Types of Promises in JavaScript

September 19, 2024 (2w ago)

Forgive me for the Typos and Grammatical Mistakes, I'm still learning. 🙏

What are Promises?

Promises are a way to handle asynchronous operations in JavaScript. They represent a value that may be available now, or in the future, or never. Promises have three states: pending, fulfilled, and rejected.

Types of Promises

  1. Pending: The initial state of a promise. It represents that the operation is still in progress and has not been completed yet.

  2. Fulfilled: The state of a promise when the operation has been completed successfully. The promise has a value, and it is available to be used.

  3. Rejected: The state of a promise when the operation has failed. The promise has a reason for the failure, and it can be handled using the catch method.

Why Promises are Important?

1. Simple Promise

const promise = new Promise((resolve, reject) => {
    // Imagine fetching user data from an API
    const user = {
        name: "Aasim Ashraf",
        age: 21,
    };
 
    user ? resolve(user) : reject("User not found");
});
 
promise
    .then((user) => console.log(user))
    .catch((error) => console.log(error));

A Promise that either resolves or rejects often used for API calls or async tasks.

2. Promise.all Multiple Operations

const fetchUser = fetch("/users").then((res) => res.json());
const fetchPosts = fetch("/posts").then((res) => res.json());
 
Promise.all([fetchUser, fetchPosts])
    .then(([user, posts]) => {
        console.log(user, posts);
    })
    .catch((error) => console.log(error));

Waits for all promises to resolve, if one fails, the whole chain fails. Best for multiple async tasks that needs to be resolved together.

What Happens if One Promise Fails in Promise.all?

const fetchUser = fetch("/users").then((res) => res.json());
const fetchPosts = fetch("/posts").then((res) => res.json());
 
Promise.all([fetchUser, fetchPosts])
    .then(([user, posts]) => {
        console.log(user, posts);
    })
    .catch((error) => console.log(error));

Problem with Promise.all is that if one promise fails, the whole chain fails. To avoid this, you can use Promise.allSettled.

3. Promise.allSettled

const fetchUser = fetch("/users").then((res) => res.json());
const fetchPosts = fetch("/posts").then((res) => res.json());
 
Promise.allSettled([fetchUser, fetchPosts])
    .then((results) => {
        results.forEach((result) => {
            if (result.status === "fulfilled") {
                console.log("User Data:", result.value);
            } else {
                console.log("Error:", result.reason);
            }
        });
    });

Promise.allSettled waits for all promises to settle, whether they are resolved or rejected. It returns an array of objects with a status and value or reason.

4. Promise.race Fastest Result

const fast = new Promise(resolve => setTimeout(resolve, 1000, "Fast"));
 
const slow = new Promise(resolve => setTimeout(resolve, 2000, "Slow"));
 
Promise.race([fast, slow])
    .then((result) => {
        console.log(result);
    })
    .catch((error) => console.log(error));

Returns the result of the first promise to settle, whether it's resolved or rejected. Useful when you need speed, such as loading the first available response.

What if a Promise in Promise.race Fails?

const error = new Promise((resolve) => {
    setTimeout(() => resolve("Error"), 1000);
});
 
const success = new Promise((resolve) => {
    setTimeout(() => resolve("Success"), 2000);
});
 
Promise.race([error, success])
    .then((result) => {
        console.log(result);
    })
    .catch((error) => console.log("First Rejected",error));

If the first promise fails, the whole chain fails. To avoid this, you can use Promise.any.

5. Promise.any First Successful Result

const promise1 = Promise.reject("Error 1");
const promise2 = new Promise(resolve => setTimeout(resolve, 3000, "Promise 2"));
 
Promise.any([promise1, promise2])
    .then((result) => {
        console.log("First Success",result);
    })
    .catch((error) => console.log("All Rejected",error));

Resolves when any one Promise is resolved. Ignores all rejections until all promises are rejected. Useful when you need the first successful result, regardless of the rest.

Recap

Final Thoughts