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, orrejected. 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.
