# Promise Methods in JavaScript – Handling Multiple Async Operations

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:

```text
User Data
Posts
Comments
```

These requests are independent.

Instead of doing:

```javascript
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:

```javascript
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:

```text
["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.

```javascript
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.

```javascript
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.

```javascript
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:

```text
[
    {
        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:

```text
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:

```javascript
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:

```text
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.

```javascript
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:

```text
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:

```javascript
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

```text
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.

```javascript
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.
