Promises
- This lesson covers how Promises simplify asynchronous programming.
Introduction to Promises
In real-world JavaScript applications, many tasks take time to complete, such as:
Fetching data from a server
Reading files
Calling APIs
Waiting for a response
Performing background tasks
JavaScript handles these tasks using asynchronous programming.
Promises are one of the most important tools in JavaScript to manage asynchronous operations in a clean and readable way.
Promises
What Is a Promise ?
A Promise is an object that represents the eventual completion or failure of an asynchronous operation.
Simple definition:
A Promise is a guarantee that a value will be returned in the future — either successfully or with an error.
Real-Life Analogy
Think of ordering food online:
You place an order (promise is created)
Food is being prepared (pending)
Food delivered (fulfilled)
Order canceled (rejected)
States of a Promise
A Promise can be in one of three states:
Pending
Initial state
Operation is still in progress
Fulfilled
Operation completed successfully
Result is available
Rejected
Operation failed
Error is returned
Once a promise is fulfilled or rejected, its state cannot be changed.
Creating a Promise
Syntax
let promise = new Promise(function (resolve, reject) {
// asynchronous operation
});
resolve() → called when task succeeds
reject() → called when task fails
JavaScript Promise Basic Example
This code demonstrates a basic Promise that resolves or rejects based on a condition (success).
let promise = new Promise(function (resolve, reject) {
let success = true;
if (success) {
resolve("Task completed successfully");
} else {
reject("Task failed");
}
});
JavaScript Promise Handling with then and catch
This code demonstrates how to handle a Promise result using .then() for success and .catch() for errors.
promise
.then(function (result) {
console.log(result);
})
.catch(function (error) {
console.log(error);
});
How Promise Execution Works (Step-by-Step)
Promise is created
Promise state is pending
Async task runs
resolve() or reject() is called
.then() handles success
.catch() handles error
JavaScript Promise with Async Delay
This code demonstrates a Promise that resolves after a delay using setTimeout, and handles the result using .then().
let myPromise = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("Data received");
}, 2000);
});
myPromise.then(function (data) {
console.log(data);
});
Why Promises Are Needed
Before promises, JavaScript used callbacks heavily, which caused problems like:
Deep nesting
Hard-to-read code
Difficult error handling
JavaScript Nested setTimeout Example
This code demonstrates nested setTimeout calls to execute asynchronous tasks in a delayed sequence.
setTimeout(function () {
setTimeout(function () {
setTimeout(function () {
console.log("Done");
}, 1000);
}, 1000);
}, 1000);
Promises help avoid this.
Promise Chaining
What Is Promise Chaining ?
Promise Chaining means executing multiple asynchronous operations one after another, where each operation depends on the result of the previous one.
This is done using multiple .then() calls.
JavaScript Promise Chaining Example
This code demonstrates Promise chaining where each .then() returns a new value that is passed to the next step in the chain, with .catch() handling errors.
promise
.then(function (result) {
return newValue;
})
.then(function (newResult) {
return anotherValue;
})
.catch(function (error) {
console.log(error);
});
- Each .then() returns a new promise.
JavaScript Promise Chaining with Value Transformation
This code demonstrates how Promise chaining passes and transforms values step-by-step through multiple .then() handlers.
let promise = new Promise(function (resolve, reject) {
resolve(10);
});
promise
.then(function (value) {
console.log(value);
return value * 2;
})
.then(function (value) {
console.log(value);
return value * 2;
})
.then(function (value) {
console.log(value);
});
JavaScript Promise Chaining with Async Steps
This code demonstrates chaining multiple Promises where each step runs asynchronously and passes its result to the next step.
function stepOne() {
return new Promise(function (resolve) {
setTimeout(() => resolve("Step 1 completed"), 1000);
});
}
function stepTwo(message) {
return new Promise(function (resolve) {
setTimeout(() => resolve(message + " → Step 2 completed"), 1000);
});
}
stepOne()
.then(function (result) {
console.log(result);
return stepTwo(result);
})
.then(function (finalResult) {
console.log(finalResult);
})
.catch(function (error) {
console.log(error);
});
Error Handling in Promise Chaining
If any promise in the chain fails:
Control jumps directly to .catch()
Remaining .then() blocks are skipped
JavaScript Promise Error Handling
This code demonstrates how errors thrown inside a Promise chain are caught and handled using .catch(), preventing further .then() execution.
promise
.then(() => {
throw new Error("Something went wrong");
})
.then(() => {
console.log("This will not run");
})
.catch((error) => {
console.log(error.message);
});
Why Promise Chaining Is Important
Improves readability
Avoids nested callbacks
Centralized error handling
Easy to maintain and debug
Common Mistakes
Forgetting to return a promise inside .then()
Writing logic inside nested .then() blocks
Not handling errors using .catch()
Mixing callbacks and promises incorrectly
Best Practices for Using Promises
Always return a promise inside .then()
Use one .catch() at the end
Keep promise logic clean and simple
Avoid unnecessary promise creation
Prefer chaining over nesting
Promises vs Callbacks (Quick Comparison)