Introduction
Promises are one of the most important features of modern JavaScript and Node.js. They provide a clean and structured way to work with asynchronous operations, making code easier to read, maintain, and debug.
Instead of relying on deeply nested callback functions, Promises allow developers to write sequential or parallel asynchronous workflows using methods such as .then(), .catch(), .finally(), Promise.all(), and Promise.race().
For automation engineers, Promises are used extensively in browser automation, API testing, database operations, file handling, and data-driven testing. Most modern automation libraries are built on top of Promises.
In this tutorial, you’ll explore several practical examples of using Promises in Node.js.
Why Use Promises?
Promises help developers:
Handle asynchronous operations.
Avoid callback hell.
Improve code readability.
Simplify error handling.
Chain multiple asynchronous tasks.
Execute parallel operations.
Build scalable applications.
Example 1: Basic Promise
Create and resolve a Promise.
const promise =
new Promise(function (
resolve,
reject
) {
resolve(
"Promise completed successfully."
);
});
promise.then(function (message) {
console.log(message);
});
Sample Output
Promise completed successfully.
Example 2: Promise with Error Handling
Reject a Promise and handle the error.
const promise =
new Promise(function (
resolve,
reject
) {
reject(
"Operation failed."
);
});
promise
.catch(function (error) {
console.log(error);
});
Sample Output
Operation failed.
Example 3: Promise Chaining
Execute multiple asynchronous operations in sequence.
Promise.resolve(5)
.then(function (value) {
return value * 2;
})
.then(function (value) {
return value + 10;
})
.then(function (value) {
console.log(value);
});
Sample Output
20
Example 4: Reading a File
Read a file using the Promise-based File System API.
const fs =
require("fs").promises;
fs.readFile(
"sample.txt",
"utf8"
)
.then(function (data) {
console.log(data);
})
.catch(function (error) {
console.log(error);
});
The Promise resolves after the file is successfully read.
Example 5: Running Multiple Tasks
Execute multiple Promises concurrently.
Promise.all([
Promise.resolve("Task 1"),
Promise.resolve("Task 2"),
Promise.resolve("Task 3")
])
.then(function (results) {
console.log(results);
});
Sample Output
[ 'Task 1', 'Task 2', 'Task 3' ]
Automation Testing Examples
Promises are widely used in automation frameworks for asynchronous operations.
Playwright Example
Open an application and log in.
Promise.resolve("Application opened.")
.then(function (message) {
console.log(message);
return "User logged in.";
})
.then(function (message) {
console.log(message);
});
Sample Output
Application opened.
User logged in.
Selenium Example
Launch a browser and navigate to a webpage.
Promise.resolve("Browser launched.")
.then(function (message) {
console.log(message);
return "Web page loaded.";
})
.then(function (message) {
console.log(message);
});
Sample Output
Browser launched.
Web page loaded.
Cypress Example
Visit a page and verify an element.
Promise.resolve("Home page opened.")
.then(function (message) {
console.log(message);
return "Element verified.";
})
.then(function (message) {
console.log(message);
});
Sample Output
Home page opened.
Element verified.
API Testing Example
Authenticate and retrieve data.
Promise.resolve("Authentication successful.")
.then(function (message) {
console.log(message);
return "User data received.";
})
.then(function (message) {
console.log(message);
});
Sample Output
Authentication successful.
User data received.
Data-Driven Testing Example
Load CSV data and execute test cases.
Promise.resolve("CSV file loaded.")
.then(function (message) {
console.log(message);
return "Test cases executed.";
})
.then(function (message) {
console.log(message);
});
Sample Output
CSV file loaded.
Test cases executed.
Real-World Uses of Promises
Promises are commonly used for:
Reading and writing files.
API requests.
Database operations.
Browser automation.
User authentication.
Sending emails.
Uploading files.
Processing JSON data.
Data validation.
Background tasks.
Common Mistakes
Forgetting to Return Values
Always return a value or another Promise from .then() when the next step depends on it.
Ignoring Errors
Always use .catch() to handle rejected Promises and unexpected exceptions.
Mixing Callbacks and Promises
Avoid mixing callback-based code with Promise-based code unless it is necessary.
Best Practices
Use Promises for asynchronous operations.
Handle errors using
.catch().Return values from
.then()methods.Use
Promise.all()for independent tasks.Use
Promise.race()for timeout and fastest-response scenarios.Keep Promise chains short and readable.
Prefer
async/awaitfor complex asynchronous workflows.
Conclusion
Promises provide a clean, powerful, and reliable way to handle asynchronous programming in JavaScript. They improve code readability, simplify error handling, and eliminate many of the problems associated with callback-based programming.
For automation engineers, Promises are a core part of modern automation frameworks. They are used for browser automation, API testing, file handling, database interactions, and concurrent task execution. Mastering practical Promise examples prepares you for working with advanced asynchronous programming techniques such as async/await.
Frequently Asked Questions (FAQs)
What is a Promise?
A Promise is an object that represents the eventual success or failure of an asynchronous operation.
Why should I use Promises?
Promises improve readability, simplify error handling, and eliminate callback hell.
What is Promise chaining?
Promise chaining connects multiple asynchronous operations using .then() so they execute in sequence.
What is Promise.all() used for?
Promise.all() executes multiple independent Promises concurrently and resolves when all of them succeed.
Why are Promises important in automation testing?
Modern automation frameworks use Promises for browser interactions, API requests, file operations, and asynchronous workflows.
Key Takeaways
Promises simplify asynchronous programming.
They provide structured success and error handling.
Use
.then()to process successful results.Use
.catch()to handle errors.Promise chaining executes dependent tasks sequentially.
Promise.all()runs independent tasks in parallel.Promise.race()returns the first settled Promise.Promises improve code readability and maintainability.
Modern Node.js applications and automation frameworks rely heavily on Promises.
Understanding Promises is essential before learning
async/await.
