codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🌐

JavaScript

47 / 65 topics
44JavaScript Callbacks45JavaScript setTimeout and setInterval46JavaScript Promises47JavaScript Promise Chaining48JavaScript async and await49JavaScript Event Loop
Tutorials/JavaScript/JavaScript Promise Chaining
🌐JavaScript

JavaScript Promise Chaining

Updated 2026-05-12
15 min read

JavaScript Promise Chaining

In the previous lesson, you learned about JavaScript Promises and how they help manage asynchronous operations. Now, let's dive deeper into a powerful feature of Promises called chaining. Promise chaining allows you to perform multiple asynchronous tasks in sequence, making your code cleaner, more readable, and easier to maintain.

Introduction

Imagine you're baking a cake. First, you need to mix the ingredients (Task 1), then preheat the oven (Task 2), after that, bake the cake (Task 3), and finally, decorate it (Task 4). Each task depends on the previous one being completed. This is similar to how Promise chaining works in JavaScript.

Promise chaining enables you to execute a series of asynchronous operations one after another. Each operation returns a Promise, and you can attach subsequent .then() methods to handle the resolved value of the previous Promise. This way, you ensure that each step waits for the previous one to finish before proceeding.

Core Content

Understanding Promise Chaining

When you return a new Promise from within a .then() method, you can chain another .then() method to it. This creates a sequence where each operation builds upon the result of the previous one.

Basic Example

Let's start with a simple example that demonstrates how to chain Promises:

promise_chain.js
1const firstPromise = new Promise((resolve, reject) => {
2setTimeout(() => resolve('First'), 1000);
3});
4
5firstPromise
6.then(result => {
7 console.log(result); // Output: First
8 return 'Second';
9})
10.then(nextResult => {
11 console.log(nextResult); // Output: Second
12 return new Promise((resolve, reject) => {
13 setTimeout(() => resolve('Third'), 1000);
14 });
15})
16.then(finalResult => {
17 console.log(finalResult); // Output: Third
18})
19.catch(error => {
20 console.error('Error:', error);
21});
Output
First
Second
Third

In this example:

  1. firstPromise resolves after 1 second with the value 'First'.
  2. The first .then() logs 'First' and returns the string 'Second'.
  3. The second .then() logs 'Second' and returns a new Promise that resolves to 'Third' after another second.
  4. The final .then() logs 'Third'.

Handling Errors in Chained Promises

It's crucial to handle errors properly when chaining Promises. If any of the Promises in the chain rejects, the execution stops at the nearest .catch() method.

Error Handling Example

Let's modify the previous example to include an error:

promise_chain_error.js
1const firstPromise = new Promise((resolve, reject) => {
2setTimeout(() => resolve('First'), 1000);
3});
4
5firstPromise
6.then(result => {
7 console.log(result); // Output: First
8 return 'Second';
9})
10.then(nextResult => {
11 console.log(nextResult); // Output: Second
12 throw new Error('Something went wrong!');
13})
14.then(finalResult => {
15 console.log(finalResult);
16})
17.catch(error => {
18 console.error('Error:', error.message); // Output: Error: Something went wrong!
19});
Output
First
Second
Error: Something went wrong!

In this example:

  1. The first two .then() methods execute successfully.
  2. The third .then() throws an error, which is caught by the .catch() method.

Returning Values in Chained Promises

When chaining Promises, you can return different types of values from each .then() method:

  • Primitive Values: Strings, numbers, etc.
  • Promises: To continue the chain with another asynchronous operation.
  • Synchronous Code: Directly returning a value.

Returning Different Types Example

Here's an example that demonstrates returning various types in a Promise chain:

promise_chain_types.js
1const firstPromise = new Promise((resolve, reject) => {
2setTimeout(() => resolve('First'), 1000);
3});
4
5firstPromise
6.then(result => {
7 console.log(result); // Output: First
8 return 'Second';
9})
10.then(nextResult => {
11 console.log(nextResult); // Output: Second
12 return new Promise((resolve, reject) => {
13 setTimeout(() => resolve('Third'), 1000);
14 });
15})
16.then(finalResult => {
17 console.log(finalResult); // Output: Third
18 return 42;
19})
20.then(number => {
21 console.log(number * 2); // Output: 84
22})
23.catch(error => {
24 console.error('Error:', error);
25});
Output
First
Second
Third
84

In this example:

  1. The first .then() returns a string 'Second'.
  2. The second .then() returns a new Promise that resolves to 'Third'.
  3. The third .then() returns the number 42.
  4. The final .then() multiplies the number by 2 and logs the result.

Common Mistakes

  1. Forgetting to Return Promises: If you return a value from a .then() method that is not a Promise, the next .then() will receive that value directly.
promise_chain_mistake.js
1const firstPromise = new Promise((resolve, reject) => {
2 setTimeout(() => resolve('First'), 1000);
3 });
4
5 firstPromise
6 .then(result => {
7 console.log(result); // Output: First
8 return 'Second';
9 })
10 .then(nextResult => {
11 console.log(nextResult.toUpperCase()); // Output: SECOND
12 return new Promise((resolve, reject) => {
13 setTimeout(() => resolve('Third'), 1000);
14 });
15 })
16 .then(finalResult => {
17 console.log(finalResult.toLowerCase()); // Output: third
18 })
19 .catch(error => {
20 console.error('Error:', error);
21 });
Output
First
 SECOND
 third
  1. Not Handling Errors: Always include a .catch() method at the end of your Promise chain to handle any unhandled errors.

Warning

Always ensure that you have a .catch() block at the end of your Promise chain to catch and handle any errors that may occur.

Practical Example

Let's create a practical example that simulates fetching user data, processing it, and then displaying it. This will demonstrate how to chain multiple asynchronous operations.

user_data.js
1function fetchUserData(userId) {
2return new Promise((resolve, reject) => {
3 setTimeout(() => {
4 const users = [
5 { id: 1, name: 'Alice', age: 25 },
6 { id: 2, name: 'Bob', age: 30 }
7 ];
8 const user = users.find(u => u.id === userId);
9 if (user) {
10 resolve(user);
11 } else {
12 reject('User not found');
13 }
14 }, 1000);
15});
16}
17
18function processUserData(user) {
19return new Promise((resolve, reject) => {
20 setTimeout(() => {
21 const processedData = { ...user, ageInMonths: user.age * 12 };
22 resolve(processedData);
23 }, 500);
24});
25}
26
27fetchUserData(1)
28.then(user => {
29 console.log('User fetched:', user);
30 return processUserData(user);
31})
32.then(processedUser => {
33 console.log('Processed User Data:', processedUser);
34})
35.catch(error => {
36 console.error('Error:', error);
37});
Output
User fetched: { id: 1, name: 'Alice', age: 25 }
Processed User Data: { id: 1, name: 'Alice', age: 25, ageInMonths: 300 }

In this example:

  1. fetchUserData(userId) simulates fetching user data from an API.
  2. processUserData(user) simulates processing the fetched user data.
  3. The Promise chain ensures that the user data is processed only after it has been successfully fetched.

Summary

  • Promise Chaining allows you to execute multiple asynchronous operations in sequence.
  • Each .then() method can return a value, another Promise, or perform synchronous code.
  • Always include a .catch() method at the end of your Promise chain to handle errors.
  • Returning non-Promise values from .then() methods directly passes them to the next .then().
ConceptDescription
Chaining PromisesExecuting multiple asynchronous operations in sequence.
Handling ErrorsUsing .catch() to handle errors that occur at any point in the chain.
Returning ValuesDifferent types of values can be returned from each .then() method.

What's Next?

In the next lesson, we'll explore JavaScript async and await, which provide a more concise and readable way to handle asynchronous operations compared to Promises. This will further enhance your ability to write clean and efficient asynchronous code.

Stay tuned for more advanced topics in JavaScript!


PreviousJavaScript PromisesNext JavaScript async and await

Recommended Gear

JavaScript PromisesJavaScript async and await