Using Promise.all in Node.js: A Step-by-Step Guide

🎓
This episode is a part of the Learn JavaScript Promises collection and is #5 episode of them all.

Introduction

Promise.all is a method in the JavaScript Promises API that allows developers to handle multiple asynchronous operations in parallel. It takes an array of Promises as its argument, and returns a new Promise that is fulfilled with an array of the fulfilled values of the input Promises, in the same order as the input Promises. If any of the input Promises are rejected, the returned Promise is also rejected. In this article, we will explore how to use Promise.all in a Node.js application to perform multiple asynchronous operations in parallel.


Step 1: Import the Promise object

To use Promise.all in Node.js, we first need to import the Promise object. We can do this by adding the following line at the top of our JavaScript file:

const Promise = require('promise');

Step 2: Create an array of Promises

Next, we need to create an array of Promises that we want to execute in parallel. Each element of the array should be a Promise, and the array should be passed as the argument to the Promise.all method. For example:

const promise1 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 100, 'foo');
});

const promise2 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 200, 'bar');
});

const promise3 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 300, 'baz');
});

const promises = [promise1, promise2, promise3];

Step 3: Call the Promise.all method

Once we have our array of Promises, we can call the Promise.all method, passing in the array as the argument.

The returned value will be a new Promise that is fulfilled with an array of the fulfilled values of the input Promises, in the same order as the input Promises. For example:

Promise.all(promises)
    .then(function(values) {
        console.log(values);
    })
    .catch(function(error) {
        console.log(error);
    });

Step 4: Handle the returned Promise

In the above example, we use the .then() and .catch() methods to handle the returned Promise. The .then() method is called if all of the input Promises are fulfilled, and is passed an array of the fulfilled values of the input Promises. The .catch() method is called if any of the input Promises are rejected, and is passed the error that caused the rejection.

Step 5: Examples of using Promise.all in a Node.js application

  • Example 1: Fetching data from multiple API endpoints

In this example, we will use the axios library to fetch data from multiple API endpoints, and use Promise.all to wait for all the requests to complete before processing the data.

const axios = require('axios');

const promise1 = axios.get('https://jsonplaceholder.typicode.com/todos/1');
const promise2 = axios.get('https://jsonplaceholder.typicode.com/todos/2');
const promise3 = axios.get('https://jsonplaceholder.typicode.com/todos/3');

const promises = [promise1, promise2, promise3];

Promise.all(promises)
    .then(function(responses) {
        const data1 = responses[0].data;
        const data2 = responses[1].data;
        const data3 = responses[2].data;
        console.log(data1, data2, data3);
    })
    .catch(function(error) {
        console.log(error);
    });

In this example, we create three Promises, each making a GET request to a different API endpoint. The returned values from the API are wrapped in a promise, so we can use them in Promise.all. The .then() method is called when all the promises are fulfilled and the data is available, and the .catch() method is called if any of the requests fail.

  • Example 2: Parallel image processing

In this example, we will use the sharp library to process multiple images in parallel, and use Promise.all to wait for all the processing to complete before displaying the images.

const sharp = require('sharp');

const image1 = sharp('image1.jpg');
const image2 = sharp('image2.jpg');
const image3 = sharp('image3.jpg');

const promise1 = image1.resize(300, 200).toBuffer();
const promise2 = image2.resize(300, 200).toBuffer();
const promise3 = image3.resize(300, 200).toBuffer();

const promises = [promise1, promise2, promise3];

Promise.all(promises)
    .then(function(images) {
        images.forEach(image => {
            console.log(image);
        });
    })
    .catch(function(error) {
        console.log(error);
    });

In this example, we create three Promises, each processing a different image using the sharp library. The returned value from the processing is wrapped in a promise, so we can use them in Promise.all. The .then() method is called when all the promises are fulfilled and the images are processed, and the .catch() method is called if any of the processing fails.

These are just a couple of examples of how Promise.all can be used in a Node.js application, but it's a very versatile tool that can be used in many different situations.


Conclusion

This article has provided a comprehensive guide on how to use the Promise.all method in a Node.js application. We have covered the basic concepts of Promises, and explained how to import the Promise object, create an array of Promises, call the Promise.all method, and handle the returned Promise. Real-world examples have been provided to illustrate how to use Promise.all to fetch data from multiple API endpoints and to process multiple images in parallel. By following the steps outlined in this article, developers can easily use Promise.all in their Node.js applications to perform multiple asynchronous operations in parallel. Whether you are a beginner or an experienced developer, this guide will help you take advantage of the power of Promise.all in your applications.