Bird
Raised Fist0
Node.jsframework~5 mins

Promise chaining in Node.js

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Promise chaining helps run multiple tasks one after another without confusing code. It makes handling steps that depend on each other easy and clear.
When you want to do one task after another, like loading data then processing it.
When you have several steps that depend on the result of the previous step.
When you want to avoid deeply nested callbacks that are hard to read.
When you want to handle errors in one place after many steps.
When you want to keep your code clean and easy to follow for asynchronous tasks.
Syntax
Node.js
function task1() {
  return new Promise((resolve, reject) => {
    // do something
    const result1 = 'result1';
    resolve(result1);
  });
}

function task2(previousResult) {
  return new Promise((resolve, reject) => {
    // use previousResult
    const result2 = 'result2';
    resolve(result2);
  });
}

task1()
  .then(result1 => task2(result1))
  .then(result2 => {
    // use result2
  })
  .catch(error => {
    // handle any error from task1 or task2
  });
Each .then() waits for the previous Promise to finish and uses its result.
Use .catch() at the end to handle errors from any step in the chain.
Examples
Simple chain where each step uses the previous value. Prints 10.
Node.js
Promise.resolve(5)
  .then(value => value * 2)
  .then(value => console.log(value));
Shows error handling in the chain. Prints 'Oops'.
Node.js
Promise.resolve()
  .then(() => {
    throw new Error('Oops');
  })
  .catch(error => console.log(error.message));
Each .then returns a Promise, chaining multiple async steps. Prints 3.
Node.js
Promise.resolve(1)
  .then(value => Promise.resolve(value + 1))
  .then(value => Promise.resolve(value + 1))
  .then(value => console.log(value));
If an error happens, later .then steps are skipped and .catch runs.
Node.js
Promise.resolve(10)
  .then(value => value + 5)
  .then(value => { throw new Error('Fail'); })
  .then(value => console.log('Won\'t run'))
  .catch(error => console.log('Error caught:', error.message));
Sample Program
This program fetches a number, adds five, then multiplies by two, showing each step's result. It uses Promise chaining to run these steps in order.
Node.js
function fetchNumber() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(10);
    }, 500);
  });
}

function addFive(number) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(number + 5);
    }, 500);
  });
}

function multiplyByTwo(number) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(number * 2);
    }, 500);
  });
}

fetchNumber()
  .then(result => {
    console.log('Fetched number:', result);
    return addFive(result);
  })
  .then(result => {
    console.log('After adding five:', result);
    return multiplyByTwo(result);
  })
  .then(result => {
    console.log('After multiplying by two:', result);
  })
  .catch(error => {
    console.error('Error:', error);
  });
OutputSuccess
Important Notes
Promise chaining runs tasks one after another, waiting for each to finish.
Time complexity depends on the tasks inside the Promises, not the chaining itself.
Common mistake: forgetting to return a Promise inside .then, which breaks the chain.
Use chaining when steps depend on each other's results; use Promise.all for parallel tasks.
Summary
Promise chaining helps run asynchronous tasks in order, using .then() for each step.
Always return a Promise inside .then() to keep the chain working.
Use .catch() at the end to handle errors from any step in the chain.

Practice

(1/5)
1. What is the main purpose of promise chaining in Node.js?
easy
A. To convert synchronous code into asynchronous code
B. To run all asynchronous tasks at the same time
C. To run asynchronous tasks one after another in order
D. To stop all asynchronous tasks immediately

Solution

  1. Step 1: Understand asynchronous task execution

    Promise chaining allows tasks to run one after another, waiting for each to finish.
  2. Step 2: Identify the purpose of chaining

    Chaining with .then() ensures order, not parallel or immediate stop.
  3. Final Answer:

    To run asynchronous tasks one after another in order -> Option C
  4. Quick Check:

    Promise chaining = ordered async tasks [OK]
Hint: Promise chaining runs tasks step-by-step, not all at once [OK]
Common Mistakes:
  • Thinking promises run in parallel by default
  • Confusing chaining with synchronous loops
  • Believing chaining stops tasks immediately
2. Which of the following is the correct syntax to chain two promises promise1 and promise2?
easy
A. promise1.then(promise2)
B. promise1.then(promise2())
C. promise1.then.then(promise2)
D. promise1.then(() => promise2())

Solution

  1. Step 1: Understand how to pass functions to .then()

    The .then() method expects a function to call when the promise resolves.
  2. Step 2: Check each option's syntax

    promise1.then(() => promise2()) correctly passes a function that calls promise2(). Options A and B call promise2() immediately or pass wrong types. promise1.then.then(promise2) has invalid chaining syntax.
  3. Final Answer:

    promise1.then(() => promise2()) -> Option D
  4. Quick Check:

    Pass a function to then() = promise1.then(() => promise2()) [OK]
Hint: Use a function inside then() to delay calling next promise [OK]
Common Mistakes:
  • Calling the next promise immediately inside then()
  • Using double then without parentheses
  • Passing promise instead of function to then()
3. What will be logged to the console when running this code?
Promise.resolve(5)
  .then(x => x + 1)
  .then(x => { throw new Error('Fail'); })
  .catch(err => 'Caught: ' + err.message)
  .then(x => console.log(x));
medium
A. Caught: Fail
B. Fail
C. 6
D. undefined

Solution

  1. Step 1: Follow the promise chain step-by-step

    The first then adds 1 to 5, resulting in 6. The second then throws an error.
  2. Step 2: Understand error handling and final output

    The catch catches the error and returns the string 'Caught: Fail'. The last then logs this string.
  3. Final Answer:

    Caught: Fail -> Option A
  4. Quick Check:

    Error caught and message logged = Caught: Fail [OK]
Hint: Errors jump to catch, then continue chain with catch result [OK]
Common Mistakes:
  • Expecting error to stop all logging
  • Thinking catch returns undefined
  • Ignoring that catch returns a value to next then
4. Identify the error in this promise chain:
fetchData()
  .then(data => processData(data))
  .then(result => console.log(result))
  .catch(console.error())
medium
A. Missing return in first then
B. Incorrect use of catch with immediate function call
C. processData is not a function
D. console.log should be inside catch

Solution

  1. Step 1: Check the catch usage

    The catch method expects a function reference, but console.error() calls the function immediately, passing its result (undefined) instead.
  2. Step 2: Correct catch usage

    It should be .catch(console.error) without parentheses to pass the function itself.
  3. Final Answer:

    Incorrect use of catch with immediate function call -> Option B
  4. Quick Check:

    Pass function to catch, not call it immediately [OK]
Hint: Pass function to catch, don't call it with () [OK]
Common Mistakes:
  • Calling catch handler immediately instead of passing function
  • Forgetting to return promises inside then
  • Misplacing console.log inside catch
5. Given these functions:
function step1() { return Promise.resolve(2); }
function step2(x) { return Promise.resolve(x * 3); }
function step3(x) { return x + 4; }

What will this code log?
step1()
  .then(x => step2(x))
  .then(x => step3(x))
  .then(console.log);
hard
A. 10
B. Promise { 10 }
C. undefined
D. Error: step3 must return a Promise

Solution

  1. Step 1: Calculate step1 and step2 results

    step1() resolves to 2. Then step2(2) resolves to 6 (2*3).
  2. Step 2: Understand step3 return and final log

    step3(6) returns 10 (6+4) synchronously. Since then accepts a value or promise, it passes 10 to next then which logs 10.
  3. Final Answer:

    10 -> Option A
  4. Quick Check:

    Sync return in then passes value = 10 [OK]
Hint: then can handle sync values; they become resolved promises [OK]
Common Mistakes:
  • Expecting step3 to return a Promise always
  • Thinking console.log logs a Promise object
  • Confusing synchronous return with Promise return