Promises in JavaScript
A Simple Guide to Understanding Asynchronous Code
Introduction
Have you ever faced this situation in JavaScript?
You write some code, expect a result immediately… but it doesn’t come on time.
Instead, your program behaves unexpectedly.
This happens because JavaScript handles many operations asynchronously.
To solve this and make code cleaner and more structured, JavaScript introduced Promises.
The Problem: Callback Hell
Before Promises, developers relied on callbacks to handle asynchronous tasks.
setTimeout(function () {
console.log("Step 1");
setTimeout(function () {
console.log("Step 2");
setTimeout(function () {
console.log("Step 3");
}, 1000);
}, 1000);
}, 1000);
Why is this a problem?
- Code becomes deeply nested
- Hard to read and understand
- Difficult to debug and maintain
This situation is called callback hell.
What is a Promise?
A Promise is a JavaScript object that represents the eventual result of an asynchronous operation.
Simple Definition
A Promise is like a commitment that:
- A result will come in the future
- It will either be successful or fail
Real-Life Analogy
Think of ordering food online:
- Pending → Order is being prepared
- Fulfilled → Food delivered successfully
- Rejected → Order cancelled
This is exactly how a Promise works.
States of a Promise
A Promise has three states:
Pending
The operation is still in progressFulfilled (Resolved)
The operation completed successfullyRejected
The operation failed
Once a Promise is completed (fulfilled or rejected), it becomes settled and cannot change.
Creating a Promise
let promise = new Promise(function (resolve, reject) {
let success = true;
if (success) {
resolve("Operation successful");
} else {
reject("Operation failed");
}
});
Using a Promise
To handle the result, we use:
-
.then()for success -
.catch()for errors
promise
.then(function (result) {
console.log(result);
})
.catch(function (error) {
console.log(error);
});
Example with Delay
let dataPromise = new Promise(function (resolve) {
setTimeout(function () {
resolve("Data received after 2 seconds");
}, 2000);
});
dataPromise.then(function (data) {
console.log(data);
});
What happens here?
- The task starts
- JavaScript continues executing other code
- After 2 seconds, the result is returned
Why Use Promises?
Promises make asynchronous code:
- Cleaner and more readable
- Easier to manage
- Free from deep nesting
They replace messy callback structures with a clear flow.
Promise Chaining
Promises allow multiple operations to be connected in sequence:
new Promise(function (resolve) {
resolve(10);
})
.then(function (num) {
return num * 2;
})
.then(function (num) {
return num * 3;
})
.then(function (result) {
console.log(result);
});
Explanation
Each .then():
- Receives the result from the previous step
- Processes it
- Passes it to the next step
Handling Errors
new Promise(function (resolve, reject) {
reject("Something went wrong");
})
.then(function (result) {
console.log(result);
})
.catch(function (error) {
console.log(error);
});
Explanation
- If something fails,
.catch()handles the error - Helps keep code clean and safe
Async/Await (Modern Approach)
Promises become even easier with async/await:
async function fetchData() {
let result = await Promise.resolve("Data loaded");
console.log(result);
}
fetchData();
Why use this?
- Looks like normal synchronous code
- Easier to read and understand
- Better debugging
Advantages of Promises
- Improves readability
- Simplifies error handling
- Supports chaining
- Works perfectly with async/await
Summary
- A Promise represents a future value
- It has three states: pending, fulfilled, and rejected
-
.then()handles success and.catch()handles errors - Promises improve code clarity and structure
Top comments (0)