Skip to main content

Command Palette

Search for a command to run...

Promise Methods in JavaScript – Handling Multiple Async Operations

Updated
6 min readView as Markdown

Over the past few days, I've learned about asynchronous JavaScript, Promises, async/await, and the Fetch API.

Today, I explored how JavaScript can handle multiple Promises together.

Instead of waiting for asynchronous operations one by one, Promise utility methods allow us to control how multiple operations should be handled.

Today, I focused on:

  • Promise.all()

  • Promise.allSettled()

  • Promise.race()

  • Promise.any()

Let's dive in.


Why Do We Need Promise Methods?

Imagine an application needs to fetch:

User Data
Posts
Comments

These requests are independent.

Instead of doing:

const users = await getUsers();

const posts = await getPosts();

const comments = await getComments();

we can start them together.

Promise methods help us decide what should happen when multiple asynchronous operations are running.


Promise.all()

Promise.all() waits for all Promises to fulfill.

Example:

const promise1 = Promise.resolve("HTML");
const promise2 = Promise.resolve("CSS");
const promise3 = Promise.resolve("JavaScript");

const result = await Promise.all([
    promise1,
    promise2,
    promise3
]);

console.log(result);

Output:

["HTML", "CSS", "JavaScript"]

The results are returned in the same order as the input Promises.


What Happens If One Promise Fails?

If one Promise rejects, Promise.all() rejects.

const promise1 = Promise.resolve("HTML");

const promise2 = Promise.reject("CSS failed");

const promise3 = Promise.resolve("JavaScript");

Promise.all([
    promise1,
    promise2,
    promise3
])
    .then(result => {
        console.log(result);
    })
    .catch(error => {
        console.error(error);
    });

The entire Promise.all() operation rejects.

This makes Promise.all() useful when every operation must succeed.


Promise.all() With API Requests

Suppose we need users and posts.

async function getData() {

    const [usersResponse, postsResponse] = await Promise.all([

        fetch("https://jsonplaceholder.typicode.com/users"),

        fetch("https://jsonplaceholder.typicode.com/posts")

    ]);

    const users = await usersResponse.json();

    const posts = await postsResponse.json();

    console.log(users);

    console.log(posts);

}

getData();

Both requests can be started without waiting for the first one to finish before starting the second.


Promise.allSettled()

Sometimes we don't want one failed Promise to prevent us from seeing the results of the others.

That's where Promise.allSettled() is useful.

const promise1 = Promise.resolve("Success");

const promise2 = Promise.reject("Failed");

const promise3 = Promise.resolve("Completed");

const results = await Promise.allSettled([
    promise1,
    promise2,
    promise3
]);

console.log(results);

The result contains information about every Promise.

For example:

[
    {
        status: "fulfilled",
        value: "Success"
    },
    {
        status: "rejected",
        reason: "Failed"
    },
    {
        status: "fulfilled",
        value: "Completed"
    }
]

When Should We Use Promise.allSettled()?

Use it when every result matters, even if some operations fail.

For example:

Send notification to 5 services

If one service fails, we may still want to know what happened with the other four.


Promise.race()

Promise.race() settles as soon as the first Promise settles.

Example:

const promise1 = new Promise(resolve => {

    setTimeout(() => {
        resolve("First");
    }, 1000);

});

const promise2 = new Promise(resolve => {

    setTimeout(() => {
        resolve("Second");
    }, 2000);

});

const result = await Promise.race([
    promise1,
    promise2
]);

console.log(result);

Output:

First

The first Promise to settle determines the result.


Important Difference: race() vs any()

This is one of the most important distinctions.

Promise.race() cares about the first Promise to settle.

That means either fulfillment or rejection can win.

Promise.any() cares about the first Promise to fulfill.


Promise.any()

Promise.any() returns the first successfully fulfilled Promise.

const promise1 = Promise.reject("Failed");

const promise2 = new Promise(resolve => {

    setTimeout(() => {
        resolve("Success!");

    }, 1000);

});

const promise3 = new Promise(resolve => {

    setTimeout(() => {
        resolve("Another success");

    }, 2000);

});

const result = await Promise.any([
    promise1,
    promise2,
    promise3
]);

console.log(result);

Output:

Success!

The rejected Promise doesn't win the race.


What If Promise.any() Fails?

If every Promise rejects, Promise.any() rejects with an AggregateError.

Example:

try {

    const result = await Promise.any([
        Promise.reject("Error 1"),
        Promise.reject("Error 2")
    ]);

    console.log(result);

} catch (error) {

    console.log(error);

}

All Promises failed, so there was no successful result to return.


Comparing Promise Methods

Method Resolves When Rejects When
Promise.all() All fulfill Any rejects
Promise.allSettled() All settle It doesn't reject because of member Promise rejection
Promise.race() First Promise settles First Promise rejects
Promise.any() First Promise fulfills All reject

This table is something I want to remember because each method solves a different problem.


Visualizing the Difference

Promise.all()
→ Wait for everyone
→ One failure = rejection

Promise.allSettled()
→ Wait for everyone
→ Give me every result

Promise.race()
→ Give me whoever settles first

Promise.any()
→ Give me whoever succeeds first

Practical Example

Imagine three servers can provide the same data.

const servers = [
    fetch("https://server-one.example/data"),
    fetch("https://server-two.example/data"),
    fetch("https://server-three.example/data")
];

If we want the first successful server, Promise.any() may be appropriate.

If we want all servers to respond successfully, Promise.all() may be appropriate.

If we want to know how every server performed, Promise.allSettled() may be appropriate.

Choosing the correct Promise method depends on what the application actually needs.


Best Practices

✔ Use Promise.all() when all operations need to succeed.

✔ Use Promise.allSettled() when you need the result of every operation regardless of failures.

✔ Use Promise.race() when the first settled result should determine the outcome.

✔ Use Promise.any() when the first successful result is what matters.

✔ Use parallel execution for independent asynchronous operations when appropriate.

✔ Still handle errors when working with Promise utilities.


My Biggest Takeaway

Today, I learned that Promises aren't just about handling one asynchronous operation.

JavaScript provides several powerful tools for coordinating multiple asynchronous operations.

The biggest distinction I learned is:

Promise.all() → Everyone must succeed

Promise.allSettled() → Tell me what happened to everyone

Promise.race() → First settled result wins

Promise.any() → First successful result wins

Understanding these methods will become extremely useful when I start building applications that make multiple API requests at the same time.

2 views

100 Days of Code: My Journey to Becoming a Full Stack Developer

Part 49 of 50

Welcome to my 100 Days of Code journey! In this series, I'll document my daily progress as I learn Full Stack Web Development from the ground up. Every post will cover what I learned, challenges I faced, mistakes I made, and the projects I built. My goal is not just to complete 100 days but to become a better developer through consistency, discipline, and learning in public. Topics I'll cover include: • Git & GitHub • HTML, CSS & JavaScript • React.js • Node.js & Express • MongoDB • APIs • Real-world Projects • AI tools for Developers Whether you're just starting out or revising your fundamentals, I hope this journey helps you learn alongside me. Let's build, learn, and grow together! 🚀

Up next

JavaScript Modules – Organizing Code Into Reusable Files

Over the past 49 days, I've built a strong foundation in JavaScript. I've learned variables, functions, arrays, objects, DOM manipulation, events, forms, APIs, Promises, and asynchronous JavaScript. T

More from this blog

T

TheSaurceCode

73 posts

Documenting my journey to becoming a Full Stack Developer through daily blogs, coding challenges, projects, tutorials, and lessons learned. Learn, build, and grow with me