Introduction
In JavaScript, some operations take time to complete. For example, getting data from a server, calling an API, reading a file, or waiting for a timer.
JavaScript should not stop the entire program while waiting for these operations. This is where Promises are useful.
A Promise allows us to handle a result that will be available now, later, or after some time.
In simple words:
A Promise means, “I will give you the result later.”
What is a Promise?
A Promise is a JavaScript object that represents the eventual completion or failure of an asynchronous operation.
For example, when we request data from a server, we don't know exactly when the server will respond.
The Promise represents that future result.
let promise = new Promise((resolve, reject) => {
// asynchronous operation
});
A Promise mainly has three states:
- Pending – The operation is still in progress.
- Fulfilled – The operation completed successfully.
- Rejected – The operation failed.
Promise States
Promise
|
Pending
/ \
/ \
Fulfilled Rejected
✅ ❌
Once a Promise becomes fulfilled or rejected, it is called settled.
Why Do We Need Promises?
Some operations in JavaScript are asynchronous. They may take some time to complete.
Examples include:
- API requests
- Server communication
- Database operations
- File operations
- Timers
For example, when we request information from a server, the response may take a few seconds.
Instead of blocking the program while waiting, JavaScript can continue doing other work and handle the result when it becomes available.
Promises provide a clean way to manage this process.
When Do We Use Promises?
Promises are mainly used when we need to work with asynchronous operations.
For example:
Request data from server
↓
Promise
↓
Wait for response
↓
┌────┴────┐
↓ ↓
Success Failure
↓ ↓
.then() .catch()
A common example is using the fetch() function to request data from an API.
How to Create a Promise
We can create a Promise using the Promise constructor.
let promise = new Promise((resolve, reject) => {
let success = true;
if (success) {
resolve("Operation successful");
} else {
reject("Operation failed");
}
});
Here:
-
resolve()indicates success. -
reject()indicates failure.
What is resolve()?
resolve() is used when an asynchronous operation is completed successfully.
resolve("Data received");
It changes the Promise from:
Pending → Fulfilled
What is reject()?
reject() is used when an operation fails.
reject("Something went wrong");
It changes the Promise from:
Pending → Rejected
Handling a Successful Promise with .then()
We use .then() to handle the successful result.
promise.then((result) => {
console.log(result);
});
If the Promise is fulfilled, the value passed to resolve() is received by .then().
Example:
let promise = new Promise((resolve, reject) => {
resolve("Data received successfully!");
});
promise.then((result) => {
console.log(result);
});
Output:
Data received successfully!
Handling Errors with .catch()
We use .catch() to handle a rejected Promise.
promise.catch((error) => {
console.log(error);
});
Example:
let promise = new Promise((resolve, reject) => {
reject("Something went wrong!");
});
promise.catch((error) => {
console.log(error);
});
Output:
Something went wrong!
.then() and .catch() Together
We can handle both success and failure using .then() and .catch().
let promise = new Promise((resolve, reject) => {
let success = true;
if (success) {
resolve("Data received!");
} else {
reject("Failed to get data!");
}
});
promise
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
The flow is:
Promise
↓
Pending
/ \
↓ ↓
resolve() reject()
↓ ↓
.then() .catch()
↓ ↓
Success Error
Real-World Example
Think about ordering food from a restaurant.
When you place an order, the food is not immediately ready.
Place Order
↓
Order is being prepared
↓
Pending
↓
┌───┴────┐
↓ ↓
Ready Cancelled
↓ ↓
Success Failure
This is similar to a Promise.
- Pending → Food is being prepared.
- Fulfilled → Food is delivered.
- Rejected → Order failed or was cancelled.
This analogy helps us understand how a Promise represents a future result.
Promise Chaining
Sometimes we need to perform multiple asynchronous operations one after another.
Promises allow us to chain multiple .then() methods.
promise
.then((result) => {
return "Step 2";
})
.then((result) => {
return "Step 3";
})
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
This is called Promise chaining.
It helps us organize multiple asynchronous operations in a readable way.
Advantages of Promises
Promises provide several benefits:
1. Better handling of asynchronous operations
They provide a structured way to handle results that arrive later.
2. Error handling
.catch() provides a convenient way to handle errors.
3. Avoid callback hell
Promises can make multiple asynchronous operations easier to read and maintain.
4. Promise chaining
Multiple asynchronous operations can be connected using .then().
Promise vs Normal Synchronous Code
Synchronous code generally executes one operation after another.
console.log("First");
console.log("Second");
console.log("Third");
Output:
First
Second
Third
With asynchronous operations, JavaScript can continue executing other code while waiting for the operation to complete.
Promises help us handle the result when the asynchronous operation finishes.
Conclusion
Promises are an important part of modern JavaScript.
They are used to handle asynchronous operations such as API requests, server communication, timers, and other tasks that take time to complete.
The most important things to remember are:
Promise
↓
Pending
↓
┌───────────────┐
↓ ↓
Fulfilled Rejected
↓ ↓
.then() .catch()
In simple terms:
A Promise represents the future result of an asynchronous operation.
Top comments (0)