A JavaScript Promise is an object representing the eventual completion or failure of an asynchronous operation. It acts as a temporary placeholder for a value that is not available yet, allowing you to write asynchronous code that resembles synchronous logic.
Think of it like ordering food online:
Pending → Order placed, waiting for preparation.
Fulfilled → Food delivered successfully.
Rejected → Order failed or canceled.
JavaScript uses Promises to handle tasks that take time, such as:
Fetching data from an API
Reading files
Database operations
Timers (setTimeout)
A Promise is a placeholder for a value that will be available now, later, or never.
Why Do We Use Promises?
JavaScript executes code line by line (single-threaded).
Some operations take time:
Fetching student details from a server
Loading marks
Loading attendance
Loading fee information
Without Promises, we would use nested callbacks, leading to Callback Hell.
Understanding with One Real Example
Imagine a Student Portal.
We need:
Student Profile
Student Marks
Student Attendance
Each request takes time.
Callback Hell
function getProfile(callback) {
setTimeout(() => {
console.log("Profile Loaded");
callback();
}, 1000);
}
function getMarks(callback) {
setTimeout(() => {
console.log("Marks Loaded");
callback();
}, 1000);
}
function getAttendance(callback) {
setTimeout(() => {
console.log("Attendance Loaded");
callback();
}, 1000);
}
getProfile(() => {
getMarks(() => {
getAttendance(() => {
console.log("Student Dashboard Ready");
});
});
});
Ouput
Profile Loaded
Marks Loaded
Attendance Loaded
Student Dashboard Ready
Problem:
getProfile
↓
getMarks
↓
getAttendance
↓
Dashboard
As tasks increase, nesting becomes messy.
Promise Version
Convert each operation into a Promise.
function getProfile() {
return new Promise(resolve => {
setTimeout(() => {
resolve("Profile Loaded");
}, 1000);
});
}
function getMarks() {
return new Promise(resolve => {
setTimeout(() => {
resolve("Marks Loaded");
}, 1000);
});
}
function getAttendance() {
return new Promise(resolve => {
setTimeout(() => {
resolve("Attendance Loaded");
}, 1000);
});
}
//Promise Chaining
//Tasks depend on each other.
getProfile()
.then(result =>{
console.log(result);
return getMarks();
})
.then(result=>{
console.log(result);
return getAttendance();
})
.then(result=>{
console.log(result);
console.log("Student Dashboard Ready");
})
Output
Profile Loaded
Marks Loaded
Attendance Loaded
Student Dashboard Ready
Much cleaner than Callback Hell.
see the below example code and how its working in all the static functions of Promise.
function getProfile() {
return new Promise(resolve => {
setTimeout(() => {
resolve("Profile Loaded");
}, 1000);
});
}
function getMarks() {
return new Promise(resolve => {
setTimeout(() => {
resolve("Marks Loaded");
}, 1000);
});
}
function getAttendance() {
return new Promise(resolve => {
setTimeout(() => {
resolve("Attendance Loaded");
}, 1000);
});
}
Promise.all()
Use when ALL tasks must succeed.
Example:
Profile, Marks, and Attendance can load simultaneously.
Promise.all([
getProfile(),
getMarks(),
getAttendance()
])
.then(results => {
console.log(results);
});
Output:
[ "Profile Loaded", "Marks Loaded", "Attendance Loaded" ]
Rule
All Success → Success
One Failure → Entire Promise Fails
Example:
Promise.all([
getProfile(),
Promise.reject("Marks Server Down"),
getAttendance()
])
.then(result=>{
console.log(result);
})
.catch(error => {
console.log(error);
});
Output
Marks Server Down
Promise.allSettled()
Use when you want every result, even failed ones.
Promise.allSettled([
getProfile(),
Promise.reject("Marks Server Down"),
getAttendance()
])
.then(results => {
console.log(results);
});
Output
[
{ status: "fulfilled", value: "Profile Loaded"},
{ status: "rejected", reason: "Marks Server Down"},
{ status: "fulfilled", value: "Attendance Loaded"}
]
Rule
Success + Failure
↓
Return Everything
Useful for dashboards where some widgets can fail.
Promise.race()
Use when you only care about the FIRST response.
Suppose data comes from multiple servers.
const server1 =
new Promise(resolve =>
setTimeout(() => resolve("Server 1"), 3000)
);
const server2 =
new Promise(resolve =>
setTimeout(() => resolve("Server 2"), 1000)
);
const server3 =
new Promise(resolve =>
setTimeout(() => resolve("Server 3"), 2000)
);
Promise.race([
server1,
server2,
server3
])
.then(result => {
console.log(result);
});
Output
Server 2
Rule
First Settled Wins
Success or failure doesn't matter.
Promise.any()
Use when you need the FIRST SUCCESS.
const server1 =
Promise.reject("Server 1 Failed");
const server2 =
new Promise(resolve =>
setTimeout(() => resolve("Server 2 Success"), 2000)
);
const server3 =
new Promise(resolve =>
setTimeout(() => resolve("Server 3 Success"), 3000)
);
Promise.any([
server1,
server2,
server3
])
.then(result => {
console.log(result);
});
Output
Server 2 Success
Rule
Ignore Failures
Return First Success
Only fails if ALL promises fail.
These are static methods of the Promise object that help you work with multiple promises at the same time.
References
https://www.geeksforgeeks.org/javascript/javascript-promise/
https://www.w3schools.com/js/js_promise.asp
https://www.programiz.com/javascript/promise

Top comments (4)
Mr.Vignesh
why this reson for use promise???
promise basic structure???
Hi bro,
Before Promises, developers often used nested callbacks, which could lead to "Callback Hell" and make code difficult to read and maintain.
Promises provide:
• Better readability
• Better error handling using
.catch()• Easier chaining of asynchronous operations using
.then()• More maintainable code
In simple terms, a Promise represents a value that will be available in the future and lets us handle the result when it arrives.
Here:
•
new Promise()creates a Promise object.•
resolve()is called when the operation succeeds.•
reject()is called when the operation fails.•
.then()handles the success result.•
.catch()handles errors.•
.finally()runs regardless of success or failure.bro I write the Example code, just see how it works in Callback Hell and also in Promise, then you get some clarity.
understand Mr.vignesh Thank you!