softare development

JavaScript promise chaining

Learn on the Go. Download the Codeflare Mobile from iOS App Store

1. What is a Promise?

Promise in JavaScript represents a value that may be:

  • Available now
  • Available later
  • Or never available

A promise has three states:

  • Pending
  • Fulfilled (resolved)
  • Rejected

2. What is Promise Chaining?

Promise chaining means linking multiple .then() calls together so that the output of one becomes the input of the next.

👉 Instead of nesting:

doSomething(function(result) {
  doNext(result, function(nextResult) {
    doAnother(nextResult, function(finalResult) {
      console.log(finalResult);
    });
  });
});

👉 You use chaining:

doSomething()
  .then(result => doNext(result))
  .then(nextResult => doAnother(nextResult))
  .then(finalResult => console.log(finalResult))
  .catch(error => console.error(error));

3. How Promise Chaining Works

Each .then():

  • Receives the result of the previous promise
  • Returns a new promise

Example:

const promise = Promise.resolve(5);

promise
  .then(num => num * 2)       // 10
  .then(num => num + 3)       // 13
  .then(num => console.log(num)); // 13

👉 Each step transforms the value and passes it forward.

4. Returning Values vs Returning Promises

✅ Returning a value:

.then(value => value * 2)

Automatically wrapped in a resolved promise.

✅ Returning a promise:

.then(value => {
  return new Promise(resolve => {
    setTimeout(() => resolve(value * 2), 1000);
  });
})

👉 The next .then() waits for it.

5. Real-World Example (API Calls)

fetch('https://api.example.com/user')
  .then(response => response.json())
  .then(user => {
    return fetch(`https://api.example.com/posts/${user.id}`);
  })
  .then(response => response.json())
  .then(posts => console.log(posts))
  .catch(error => console.error(error));

👉 Flow:

  1. Fetch user
  2. Use user ID to fetch posts
  3. Output posts

6. Error Handling in Chaining

Errors propagate down the chain until caught.

doSomething()
  .then(result => {
    throw new Error("Something went wrong");
  })
  .then(() => {
    console.log("This will not run");
  })
  .catch(err => {
    console.error(err.message);
  });

🔸 Important Rule:

👉 A single .catch() can handle errors from all previous .then() calls.

7. Using .finally()

.finally() runs no matter what:

fetchData()
  .then(data => console.log(data))
  .catch(err => console.error(err))
  .finally(() => console.log("Done"));

8. Common Mistakes in Promise Chaining

❌ Not returning a promise

.then(result => {
  fetchData(result); // missing return
})

👉 Fix:

.then(result => {
  return fetchData(result);
})

❌ Nested .then() (anti-pattern)

.then(result => {
  fetchData(result).then(data => {
    console.log(data);
  });
})

👉 Fix:

.then(result => fetchData(result))
.then(data => console.log(data));

9. Parallel vs Sequential Chaining

Sequential (Chaining)

Runs one after another:

task1()
  .then(result => task2(result))
  .then(result => task3(result));

Parallel (Promise.all)

Runs all at once:

Promise.all([task1(), task2(), task3()])
  .then(results => console.log(results));

10. Promise Chaining vs Async/Await

Promise chaining:

getUser()
  .then(user => getPosts(user.id))
  .then(posts => console.log(posts))
  .catch(err => console.error(err));

Async/Await (cleaner):

async function getData() {
  try {
    const user = await getUser();
    const posts = await getPosts(user.id);
    console.log(posts);
  } catch (err) {
    console.error(err);
  }
}

👉 Async/await is just syntactic sugar over promise chaining.

11. Advanced Pattern: Dynamic Chains

const tasks = [1, 2, 3];

tasks.reduce((promise, task) => {
  return promise.then(() => {
    return new Promise(resolve => {
      setTimeout(() => {
        console.log(task);
        resolve();
      }, 1000);
    });
  });
}, Promise.resolve());

👉 Executes tasks one after another.

12. Mental Model (Very Important)

Think of promise chaining like a pipeline:

Input → then() → then() → then() → catch()

Each stage:

  • Processes data
  • Passes it forward
  • Or throws an error

13. Best Practices

✔ Always return values or promises in .then()
✔ Use a single .catch() at the end
✔ Avoid nested .then()
✔ Use .finally() for cleanup
✔ Prefer async/await for readability in complex flows

Final Insight

Promise chaining is what made JavaScript move from messy callbacks to structured async programming. It’s the foundation behind:

  • API calls
  • File handling
  • Database queries
  • Modern frameworks like React, Node.js

Recent Posts

UI/UX Design — Explained Like You’re 5

Download the Codeflare iOS app and learn on the Go 1. What UI and UX…

2 weeks ago

Costly Linux Mistakes Beginners Make

1. Running Everything as Root One of the biggest beginner errors. Many new users log…

1 month ago

How Keyloggers Work

A keylogger is a type of surveillance software or hardware that records every keystroke made…

2 months ago

JavaScript Memoization

In JavaScript, it’s commonly used for: Recursive functions (like Fibonacci) Heavy calculations Repeated API/data processing…

2 months ago

CSS Container Queries: Responsive Design That Actually Makes Sense

For years, responsive design has depended almost entirely on media queries. We ask questions like: “If…

2 months ago

Cron Jobs & Task Scheduling

1. What is Task Scheduling? Task scheduling is the process of automatically running commands, scripts,…

2 months ago