Node.js Promises Practice Questions with Solutions

Introduction

Promises are an important way to handle asynchronous operations in Node.js. A Promise represents a value that may be available now, later, or may fail. In this chapter, you will practice creating Promises, handling resolved and rejected Promises, using .then(), .catch(), .finally(), chaining Promises, Promise.all(), Promise.allSettled(), Promise.race(), and practical Node.js examples. The questions gradually move from beginner concepts to real-world usage. Node.js Promises practice questions with solutions help to understand the concepts.

Question 1: How do you create a simple Promise?

Problem

Create a Promise that successfully returns a message.

Solution

const myPromise = new Promise((resolve, reject) => {

    resolve("Promise completed successfully.");

});

console.log(myPromise);

Output

Promise { 'Promise completed successfully.' }

The exact console representation can vary by Node.js version.

Step-by-Step Explanation

A Promise is created using:

new Promise((resolve, reject) => {
    // Code
});

It has two important functions:

resolve → successful operation
reject  → failed operation

In this example:

resolve("Promise completed successfully.");

marks the Promise as successfully completed.


Question 2: How do you handle a resolved Promise using then()?

Problem

Create a Promise and display its result using .then().

Solution

const myPromise = new Promise((resolve, reject) => {

    resolve("Data received successfully.");

});

myPromise.then((result) => {

    console.log(result);

});

Output

Data received successfully.

Step-by-Step Explanation

The Promise resolves with:

resolve("Data received successfully.");

The .then() method receives the resolved value:

myPromise.then((result) => {
    console.log(result);
});

So the value passed to resolve() becomes the result received by .then().


Question 3: How do you handle a rejected Promise using catch()?

Problem

Create a Promise that fails and handle the error using .catch().

Solution

const myPromise = new Promise((resolve, reject) => {

    reject(new Error("Unable to load data."));

});

myPromise
    .then((result) => {

        console.log(result);

    })
    .catch((error) => {

        console.log("Error:", error.message);

    });

Output

Error: Unable to load data.

Step-by-Step Explanation

The Promise is rejected:

reject(new Error("Unable to load data."));

Because the Promise failed, the .catch() block handles the error:

.catch((error) => {
    console.log(error.message);
});

Question 4: How do you create a Promise with setTimeout()?

Problem

Create a Promise that waits for two seconds before resolving.

Solution

function getMessage() {

    return new Promise((resolve, reject) => {

        setTimeout(() => {

            resolve("Data loaded after 2 seconds.");

        }, 2000);

    });
}

getMessage().then((message) => {

    console.log(message);

});

Output

Immediately:


After approximately 2 seconds:

Data loaded after 2 seconds.

Step-by-Step Explanation

The function returns a Promise:

return new Promise((resolve, reject) => {

setTimeout() waits for approximately two seconds:

setTimeout(() => {
    resolve("Data loaded after 2 seconds.");
}, 2000);

After the timer completes, the Promise is resolved.

The .then() method receives the result.


Question 5: How do you use finally() with a Promise?

Problem

Create a Promise and execute some code after the Promise finishes, regardless of whether it succeeds or fails.

Solution

const myPromise = new Promise((resolve, reject) => {

    resolve("Operation completed.");

});

myPromise
    .then((result) => {

        console.log(result);

    })
    .catch((error) => {

        console.log("Error:", error.message);

    })
    .finally(() => {

        console.log("Operation finished.");

    });

Output

Operation completed.
Operation finished.

Step-by-Step Explanation

.finally() executes after the Promise settles.

It runs whether the Promise:

  • resolves
  • rejects

Example:

.finally(() => {
    console.log("Operation finished.");
});

Question 6: How do you chain multiple Promises?

Problem

Create three asynchronous tasks and execute them one after another using Promise chaining.

Solution

function firstTask() {

    return new Promise((resolve) => {

        setTimeout(() => {

            console.log("First task completed.");

            resolve();

        }, 1000);

    });
}

function secondTask() {

    return new Promise((resolve) => {

        setTimeout(() => {

            console.log("Second task completed.");

            resolve();

        }, 1000);

    });
}

function thirdTask() {

    return new Promise((resolve) => {

        setTimeout(() => {

            console.log("Third task completed.");

            resolve();

        }, 1000);

    });
}

firstTask()
    .then(() => secondTask())
    .then(() => thirdTask())
    .then(() => {

        console.log("All tasks completed.");

    })
    .catch((error) => {

        console.log("Error:", error.message);

    });

Output

After approximately one second:

First task completed.

After approximately two seconds:

Second task completed.

After approximately three seconds:

Third task completed.
All tasks completed.

Step-by-Step Explanation

First:

firstTask()

returns a Promise.

When it finishes:

.then(() => secondTask())

starts the second task.

After that:

.then(() => thirdTask())

starts the third task.

Finally:

.then(() => {
    console.log("All tasks completed.");
});

runs after all three operations finish.


Question 7: How do you use Promise.all()?

Problem

Run multiple Promises together and display all their results when every Promise succeeds.

Solution

function getUser() {

    return Promise.resolve("User data");
}

function getCourses() {

    return Promise.resolve("Course data");
}

function getMessages() {

    return Promise.resolve("Message data");
}

Promise.all([
    getUser(),
    getCourses(),
    getMessages()
])
.then((results) => {

    console.log(results);

})
.catch((error) => {

    console.log("Error:", error.message);

});

Output

[
  'User data',
  'Course data',
  'Message data'
]

Step-by-Step Explanation

Promise.all() accepts an array of Promises:

Promise.all([
    getUser(),
    getCourses(),
    getMessages()
])

When all Promises resolve, .then() receives an array containing their results.

The result order matches the order of the Promises passed to Promise.all().


Question 8: How do you use Promise.allSettled()?

Problem

Run multiple Promises and receive the result of every Promise, whether it succeeds or fails.

Solution

const promise1 = Promise.resolve("Task 1 completed.");

const promise2 = Promise.reject(
    new Error("Task 2 failed.")
);

const promise3 = Promise.resolve("Task 3 completed.");

Promise.allSettled([
    promise1,
    promise2,
    promise3
])
.then((results) => {

    console.log(results);

});

Output

The result will contain entries similar to:

[
  {
    status: 'fulfilled',
    value: 'Task 1 completed.'
  },
  {
    status: 'rejected',
    reason: Error: Task 2 failed.
  },
  {
    status: 'fulfilled',
    value: 'Task 3 completed.'
  }
]

The exact formatting can vary by Node.js version.

Step-by-Step Explanation

Unlike Promise.all(), Promise.allSettled() waits for every Promise to finish.

It reports:

fulfilled → Promise succeeded
rejected  → Promise failed

Question 9: How do you use Promise.race()?

Problem

Create two Promises with different completion times and determine which one finishes first.

Solution

const fastTask = new Promise((resolve) => {

    setTimeout(() => {

        resolve("Fast task completed.");

    }, 1000);

});

const slowTask = new Promise((resolve) => {

    setTimeout(() => {

        resolve("Slow task completed.");

    }, 3000);

});

Promise.race([
    fastTask,
    slowTask
])
.then((result) => {

    console.log(result);

})
.catch((error) => {

    console.log("Error:", error.message);

});

Output

After approximately one second:

Fast task completed.

Step-by-Step Explanation

The first Promise finishes after one second.

The second finishes after three seconds.

Promise.race() settles when the first Promise settles.

Fast Task → 1 second
Slow Task → 3 seconds

Winner → Fast Task

Question 10: How do you build a practical Node.js Promise-based application?

Problem

Create a small Node.js application that:

  • Reads student data from a JSON file.
  • Uses a Promise.
  • Handles file errors.
  • Handles invalid JSON.
  • Returns student data.
  • Uses .then(), .catch(), and .finally().

Solution

First create students.json:

[
    {
        "id": 1,
        "name": "Rahul",
        "course": "Node.js"
    },
    {
        "id": 2,
        "name": "Priya",
        "course": "JavaScript"
    }
]

Create index.js:

const fs = require("fs");

function getStudents() {

    return new Promise((resolve, reject) => {

        fs.readFile(
            "students.json",
            "utf8",
            (error, data) => {

                if (error) {

                    reject(
                        new Error(
                            "Unable to read students file."
                        )
                    );

                    return;
                }

                try {

                    const students = JSON.parse(data);

                    resolve(students);

                } catch (error) {

                    reject(
                        new Error(
                            "Invalid student JSON data."
                        )
                    );
                }
            }
        );
    });
}

console.log("Loading students...");

getStudents()
    .then((students) => {

        console.log("Students:");

        students.forEach((student) => {

            console.log(
                `${student.id}. ${student.name} - ${student.course}`
            );

        });

    })
    .catch((error) => {

        console.log("Error:", error.message);

    })
    .finally(() => {

        console.log("Student operation finished.");

    });

Output

Loading students...
Students:
1. Rahul - Node.js
2. Priya - JavaScript
Student operation finished.

Step-by-Step Explanation

Step 1: Import the File System module

const fs = require("fs");

Step 2: Create a Promise-based function

function getStudents() {
    return new Promise((resolve, reject) => {
        // Code
    });
}

The function returns a Promise.

Step 3: Read the file

fs.readFile(
    "students.json",
    "utf8",
    (error, data) => {

The file is read asynchronously.

Step 4: Reject if the file cannot be read

if (error) {
    reject(
        new Error("Unable to read students file.")
    );

    return;
}

Step 5: Parse the JSON

const students = JSON.parse(data);

Step 6: Resolve with the student data

resolve(students);

Step 7: Handle successful data

.then((students) => {
    // Display students
})

Step 8: Handle errors

.catch((error) => {
    console.log(error.message);
})

Step 9: Perform final cleanup

.finally(() => {
    console.log("Student operation finished.");
});

Key Takeaways

  • A Promise represents the eventual result of an asynchronous operation.
  • A Promise can be pending, fulfilled, or rejected.
  • resolve() marks a Promise as successfully completed.
  • reject() marks a Promise as failed.
  • .then() handles a successful Promise result.
  • .catch() handles a rejected Promise.
  • .finally() runs after a Promise settles, whether it succeeds or fails.
  • Promise chaining allows multiple asynchronous operations to run in sequence.
  • Promises can make complex asynchronous code easier to read than deeply nested callbacks.
  • Promise.all() waits for all Promises to fulfill.
  • Promise.all() rejects when one of its input Promises rejects.
  • Promise.allSettled() waits for every Promise and reports both successes and failures.
  • Promise.race() settles when the first input Promise settles.
  • A rejected Promise should be handled properly to avoid unhandled Promise rejection warnings or errors.
  • Promises can be used with Node.js modules such as fs.
  • Callback-based APIs can be wrapped inside Promises.
  • Promise-based functions can later be used with async/await.
  • Understanding Promises is important before learning advanced asynchronous Node.js programming.

FAQs

1. What is a Promise in Node.js?

A Promise is a JavaScript object that represents the eventual completion or failure of an asynchronous operation.

A Promise can be:

Pending
Fulfilled
Rejected

For example:

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

promise.then((result) => {
    console.log(result);
});

2. What is the difference between resolve() and reject()?

resolve() indicates that the operation completed successfully.

resolve("Success");

reject() indicates that the operation failed.

reject(new Error("Something went wrong."));

The resolved value is normally handled with .then(), while the rejection is handled with .catch().

3. What is the difference between then() and catch()?

.then() is commonly used to handle a successful Promise:

promise.then((result) => {
    console.log(result);
});

.catch() is used to handle a rejected Promise:

promise.catch((error) => {
    console.log(error.message);
});

Both can be combined:

promise
    .then((result) => {
        console.log(result);
    })
    .catch((error) => {
        console.log(error.message);
    });

4. What is Promise.all() in Node.js?

Promise.all() runs multiple Promises together and fulfills when all of them fulfill.

Example:

Promise.all([
    getUser(),
    getCourses(),
    getMessages()
])
.then((results) => {
    console.log(results);
});

If one of the input Promises rejects, the resulting Promise.all() Promise rejects.

5. What is the difference between Promise.all() and Promise.allSettled()?

Promise.all() rejects when one of its input Promises rejects.

Promise.all()
↓
One rejection
↓
Overall rejection

Promise.allSettled() waits for every Promise:

Promise.allSettled()
↓
Wait for every Promise
↓
Report fulfilled + rejected results

Use Promise.allSettled() when you need the outcome of every operation.

6. What is Promise.race()?

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

Example:

Promise.race([
    fastTask,
    slowTask
])
.then((result) => {
    console.log(result);
});

If fastTask finishes first, its result is returned by the race.

7. Are Promises better than callbacks?

Promises are not simply “better” in every situation. They provide a cleaner way to manage many asynchronous operations, especially when operations need to be chained.

Callbacks are still important in Node.js because many older APIs and libraries use them.

Promises also make it possible to use async/await, which often makes asynchronous code easier to read.

Written by Shubhranshu Shekhar, who has trained 20000+ students in coding.

Scroll to Top