Promise Chaining0%

Promise Chaining

Beginner12 min read•Updated: Jul 11, 2026
Study Materials

Promise Chaining in Modern JavaScript

One of the greatest advantages of Promises over callbacks is Promise Chaining. Because .then() always returns a brand-new Promise, you can chain sequential asynchronous operations into a clean, flat, readable pipeline with centralized error handling.


1. How Chaining Works

Whenever you return a value inside a .then() handler, the next .then() receives that value wrapped in a resolved Promise:

JavaScript
Promise.resolve(5)
.then(num => {
console.log('Step 1:', num); // 5
return num * 2; // Returns 10
})
.then(doubled => {
console.log('Step 2:', doubled); // 10
return doubled + 20; // Returns 30
})
.then(finalSum => {
console.log('Step 3:', finalSum); // 30
});

2. Returning Promises Inside .then()

If you return a new Promise from inside a .then() callback, the chain will pause until that inner Promise settles:

JavaScript
function fetchUser(userId) {
return Promise.resolve({ id: userId, name: 'Elena' });
}
 
function fetchUserPermissions(userId) {
return Promise.resolve(['read', 'write', 'admin']);
}
 
// Flat, sequential asynchronous chain:
fetchUser(101)
.then(user => {
console.log(`Fetched user: ${user.name}`);
return fetchUserPermissions(user.id); // Returning another Promise!
})
.then(permissions => {
console.log('Fetched permissions:', permissions);
})
.catch(err => {
console.error('Error occurred anywhere in the chain:', err);
});
Output
Execution Timeline:
fetchUser(101) ──────► Fulfilled ({ name: 'Elena' })
│
fetchUserPermissions(101) ──► Fulfilled (['read', 'write'])
│
Final .then()

3. Centralized Error Handling

In a Promise chain, errors trickle down until they find the nearest .catch() handler. A single .catch() at the end can handle errors originating from any preceding step:

JavaScript
fetchUserProfile()
.then(profile => validateProfile(profile))
.then(validData => saveToDatabase(validData))
.then(record => sendConfirmationEmail(record.email))
.catch(error => {
// Catches validation failures, database errors, OR email errors!
console.error('Pipeline failed:', error.message);
});

4. Recovering from Errors in a Chain

If you return a fallback value from inside .catch(), subsequent .then() handlers can continue execution:

JavaScript
function loadCachedConfig() {
return { theme: 'default', offline: true };
}
 
fetchRemoteConfig()
.catch(err => {
console.warn('Remote config failed, falling back to cache...');
return loadCachedConfig(); // Recover by returning fallback
})
.then(config => {
console.log('Active configuration:', config); // Executes successfully!
});

5. Parallel Promise Combinators

When operations are independent and do not rely on each other, run them concurrently:

MethodBehaviorResolves When...Rejects When...
Promise.all()Fail-fast parallel batchAll fulfillAny single promise rejects
Promise.allSettled()Complete auditAll settle (fulfilled or rejected)Never rejects
Promise.race()First responderFirst promise settlesFirst promise settles
Promise.any()First successFirst promise fulfillsAll promises reject (AggregateError)
JavaScript
// Run 3 independent API requests simultaneously:
const [users, products, settings] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/products').then(r => r.json()),
fetch('/api/settings').then(r => r.json())
]);

Interactive Quiz

Practice Quiz

Question 1
What does a .then() handler return if it does not contain an explicit return statement?
Question 2
How does Promise.all() behave if one of the promises in the array rejects?
Question 3
Which Promise method waits for all promises to finish and returns an array of status objects ({ status, value/reason }) without rejecting?
Question 4
If an error is thrown inside the first .then() of a 4-step chain, where does control jump?
Question 5
What is the primary difference between Promise.any() and Promise.race()?
Next Lesson

Intro to Async/Await

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Related Lessons

Previous LessonNext Lesson
Promises BasicsIntro to Async/Await

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext