How to wait for multiple Promises?
Tags: node, javascript
Published: 2021-07-09 10:44:27

---
title: How to wait for multiple Promises?
published: true
date: 2021-03-26 00:00:00 UTC
tags: node, javascript
canonical_url: https://www.mariokandut.com/how-to-wait-for-multiple-promises-in-node-javascript/
---

In some use cases in Node.js it's needed to execute multiple asynchronous operations concurrently and wait for them all to complete, because the combined result has to be processed. An example of this would be to wait for multiple API calls to finish before collecting all results and create a new combined API call. There are several ways to accomplish this. You can do this with the `async/await` and `try/catch pattern` or with the`Promise.all()` method. This blog article is about the latter one.

For an overview of promises in Node.js have a look at the article: [Promises in Node.js](https://www.mariokandut.com/understanding-promises-in-node-js/)

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#promisealliterable)Promise.all(iterable)

**Promise.all** waits for all fulfillments (or the first rejection).

- Syntax: `Promise.all(iterable)`
- Parameters: `iterable` - An iterable object such as an Array.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#what-is-promiseall)What is Promise.all?

The `Promise.all()` method takes **an iterable of promises as an input** (commonly an array), and **returns a single Promise** that resolves to an array of the results of the input promises.

This **returned Promise will resolve** when **all the input promises have resolved** , or if the input iterable contains no promises.

It **rejects immediately** upon **any of the input promises rejecting or non-promises throwing an error** , and will reject with this first rejection message / error.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#how-to-use-promiseall)How to use Promise.all

The `Promise.all` method needs an iterable as an input, an array with promises and it will behave as a single Promise. So we can add a `.then` handler to handle the returned Promise, which will receive the result of the resolved Promises. To catch and handle potential errors a `catch` handler should be attached as well.

Let's look at an example. We create 3 promises each with a different timeout. When all promises are resolved, it should output the combined response.

```
const all = Promise.all([
  new Promise((resolve, reject) =>
    setTimeout(() => resolve(1), 1000),
  ),
  new Promise((resolve, reject) =>
    setTimeout(() => resolve(2), 2000),
  ),
  new Promise((resolve, reject) =>
    setTimeout(() => resolve(3), 3000),
  ),
]).catch(err => console.log('Promise was rejected!', err));

all.then(results => console.log(results)); // the output is: [1, 2, 3]
```

Please note that **all inner Promises are started at the same time** , so it takes 3 seconds instead of 6 seconds (1+2+3).

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#example-with-node-fetch)Example with node-fetch

Let's look at a more real example. We make a request for each element in an array. In the example we are going to request five todos based on their id from a placeholder API.

Create a project folder.

```
mkdir node-promise-all
```

Initialize project with `npm init -y` to be able to install node packages.

```
cd node-organize
npm init -y
```

Install `node-fetch` to make fetch requests.

```
npm install node-fetch
```

Create an `index.js` file.

```
touch index.js
```

Add code.

```
// import node-fetch
const fetch = require('node-fetch');
// set url as constant
const URL = 'https://jsonplaceholder.typicode.com/todos';
const ids = [1, 2, 3, 4, 5];

// create a request for each todo id and decode as json.
// json() returns a Promise
const getTodo = id =>
  fetch(`${URL}/${id}`).then(response => response.json());

// Map over the ids, returning a promise for each one.
const arrayOfPromises = ids.map(id => getTodo(id));

// create a single Promise for all the Promises
Promise.all(arrayOfPromises)
  .then(todos => todos.map(todo => todo.title))
  .then(titles => console.log(titles)) // logs titles from all the todos
  .catch(err => console.log(err));
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#fault-tolerant-promiseall)Fault-tolerant Promise.all

If one Promise in the iterable object throws an error, all other Promises will be halted and if there have been already successfully made requests the results will not be returned. To still receive the result from `Promise.all` in a case where some Promises reject, we need to make the Promise.all utility **fault tolerant**.

To avoid losing the other responses, a catch handler can be attached to the individual Promises. This way we are catching the errors they might throw, instead of letting them bubble up to the Promise.all, which will cause the Promise to reject. The code could look something like this:

```
const promises = [
  fetch(url),
  fetch(url),
  Promise.reject(new Error('This fails!')),
  fetch(url),
];
const allPromisesWithErrorHandler = promises.map(promise =>
  promise.catch(error => error),
);

Promise.all(allPromisesWithErrorHandler).then(results => {
  // we get results even if a promise returns rejected!
  // But results can be a mix of errors and success values.
  console.log(results);
});
```

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#tldr)TL;DR

- `Promise.all` is useful to make several asynchronous calls and collect all their results together.
- The method `Promise.all` waits for all fulfillments (or the first rejection).
- When writing async code `Promise.all` helps us to write cleaner and maintainable code.

Thanks for reading and if you have any **questions** , use the **comment** function or **send me a message** **[@mariokandut](https://www.twitter.com/mariokandut)**.

If you want to know more about **[Node](https://www.mariokandut.com/tags/node)**, have a look at these [Node Tutorials](https://www.mariokandut.com/tags/node).

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#references-and-big-thanks)References (and Big thanks):

[HeyNode](https://heynode.com/tutorial/organize-your-nodejs-code-modules/),[node-fetch](https://www.npmjs.com/package/node-fetch),[MDN - Promise.all()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all)