Bird
Raised Fist0
Javascriptprogramming~10 mins

Promise chaining in Javascript - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Promise chaining
Start with initial Promise
↓
First .then() callback runs
↓
Return value or Promise
↓
Next .then() waits for previous result
↓
Next .then() callback runs
↓
Repeat until chain ends
↓
Final result
A Promise chain runs each .then() after the previous Promise resolves, passing results along.
Execution Sample
Javascript
Promise.resolve(1)
  .then(x => x + 1)
  .then(x => Promise.resolve(x + 1))
  .then(console.log);
This code starts with 1, adds 1, then adds 1 again asynchronously, and logs the final result.
Execution Table
StepActionInputOutput/ReturnedNext Step
1Promise.resolve(1) creates resolved Promise-Promise resolved with 1Call first .then() with 1
2First .then() callback runs1Returns 2 (1 + 1)Pass 2 to next .then()
3Second .then() callback runs2Returns Promise resolved with 3Wait for Promise to resolve
4Promise from step 3 resolves-3Pass 3 to next .then()
5Third .then() callback runs (console.log)3Logs 3 to consoleChain ends
💡 All .then() callbacks completed, final value 3 logged, chain ends.
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 4Final
x-2233
Key Moments - 3 Insights
Why does the second .then() return a Promise instead of a direct value?
Because returning Promise.resolve(x + 1) creates a new Promise that delays the next .then() until it resolves, as shown in execution_table step 3 and 4.
How does the value pass from one .then() to the next?
Each .then() receives the resolved value from the previous Promise, either directly or after waiting for a returned Promise to resolve, as seen in execution_table steps 2, 4, and 5.
What happens if a .then() returns a non-Promise value?
It is wrapped automatically in a resolved Promise, so the next .then() receives it immediately, like in step 2 where 2 is returned directly.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of 'x' after step 3?
A1
B2
C3
DPromise
💡 Hint
Check the 'Output/Returned' column at step 3 in execution_table.
At which step does the Promise returned by the second .then() resolve?
AStep 4
BStep 2
CStep 3
DStep 5
💡 Hint
Look for the row mentioning 'Promise from step 3 resolves' in execution_table.
If the first .then() returned Promise.resolve(x + 1) instead of x + 1, how would the execution_table change?
AStep 4 would be skipped
BStep 2 would return a direct value and step 3 would run immediately
CStep 2 would return a Promise and step 3 would wait for it to resolve
DThe final console.log would log a Promise object
💡 Hint
Recall how returning a Promise delays the next .then() until resolution, as shown in steps 3 and 4.
Concept Snapshot
Promise chaining syntax:
Promise.resolve(value)
  .then(result => newResult)
  .then(nextResult => ...);

Each .then() waits for the previous Promise to resolve.
Return a value for immediate next step.
Return a Promise to delay next step until it resolves.
Full Transcript
Promise chaining means running multiple .then() callbacks one after another. Each .then() waits for the previous Promise to finish and passes its result forward. If a .then() returns a direct value, the next .then() runs immediately with that value. If it returns a Promise, the next .then() waits for that Promise to resolve before running. This lets us write steps that happen in order, even if some are asynchronous. In the example, we start with 1, add 1, then add 1 again asynchronously, and finally log 3. The execution table shows each step clearly, tracking inputs and outputs. This helps beginners see how values flow through the chain.

Practice

(1/5)
1. What does promise chaining allow you to do in JavaScript?
easy
A. Run multiple synchronous tasks at the same time
B. Stop all asynchronous tasks immediately
C. Run asynchronous tasks one after another, passing results along
D. Convert promises into synchronous functions

Solution

  1. Step 1: Understand the purpose of promise chaining

    Promise chaining is designed to run async tasks in sequence, where each step waits for the previous to finish and can use its result.
  2. Step 2: Compare options with the concept

    Only Run asynchronous tasks one after another, passing results along correctly describes running async tasks one after another and passing results along.
  3. Final Answer:

    Run asynchronous tasks one after another, passing results along -> Option C
  4. Quick Check:

    Promise chaining = sequential async tasks [OK]
Hint: Promise chaining runs async tasks in order [OK]
Common Mistakes:
  • Thinking promises run synchronously
  • Believing chaining stops tasks immediately
  • Confusing promise chaining with parallel execution
2. Which of the following is the correct syntax to chain two promises p1 and p2?
easy
A. p1.then().then(p2).then(result => console.log(result));
B. p1.then(() => p2).then(result => console.log(result));
C. p1.then(p2).then(result => console.log(result));
D. p1.then(result => p2).catch(console.log);

Solution

  1. Step 1: Understand promise chaining syntax

    To chain promises, the first promise's then should return the second promise function call, so it waits for it.
  2. Step 2: Analyze each option

    p1.then(() => p2).then(result => console.log(result)); correctly returns p2 inside then. p1.then(p2).then(result => console.log(result)); passes p2 directly, which is incorrect. p1.then().then(p2).then(result => console.log(result)); has an empty then() which is invalid. p1.then(result => p2).catch(console.log); uses catch prematurely and returns p2 incorrectly.
  3. Final Answer:

    p1.then(() => p2).then(result => console.log(result)); -> Option B
  4. Quick Check:

    Return next promise in then = correct chaining [OK]
Hint: Return next promise inside then() for chaining [OK]
Common Mistakes:
  • Passing promise directly to then instead of a function
  • Leaving then() empty
  • Misplacing catch before chain ends
3. What will be the output of this code?
Promise.resolve(5)
  .then(x => x * 2)
  .then(x => Promise.resolve(x + 3))
  .then(console.log);
medium
A. Error
B. 10
C. Promise { 13 }
D. 13

Solution

  1. Step 1: Trace each then step

    First, Promise.resolve(5) resolves with 5. Then x => x * 2 returns 10. Next, x => Promise.resolve(x + 3) returns a promise resolving to 13.
  2. Step 2: Understand final then output

    The last then(console.log) logs the resolved value 13, not a promise object.
  3. Final Answer:

    13 -> Option D
  4. Quick Check:

    Promise chaining unwraps nested promises [OK]
Hint: Promises unwrap nested promises automatically [OK]
Common Mistakes:
  • Thinking console.log prints a Promise object
  • Ignoring that then unwraps promises
  • Confusing multiplication and addition order
4. Find the error in this promise chain:
fetchData()
  .then(data => processData(data))
  .then(result => console.log(result))
  .catch(error => console.error(error));

function processData(data) {
  throw new Error('Processing failed');
}
medium
A. Error is caught by catch because thrown inside then chain
B. catch should be before then to catch errors
C. Missing return statement in processData causes error
D. Error is not caught because processData is synchronous

Solution

  1. Step 1: Understand error throwing in promise chain

    Throwing an error inside processData causes the promise to reject, which is caught by the catch at the end.
  2. Step 2: Analyze catch placement and behavior

    The catch at the end catches any error thrown in previous then callbacks, including synchronous throws.
  3. Final Answer:

    Error is caught by catch because thrown inside then chain -> Option A
  4. Quick Check:

    Thrown errors in then are caught by catch [OK]
Hint: Errors thrown in then are caught by catch at chain end [OK]
Common Mistakes:
  • Thinking synchronous errors are not caught
  • Placing catch before then incorrectly
  • Assuming missing return causes error
5. You want to run three async tasks task1, task2, and task3 in order, where each depends on the previous result. Which code correctly chains them and catches any error once?
hard
A. task1() .then(result1 => task2(result1)) .then(result2 => task3(result2)) .catch(error => console.error(error));
B. task1() .then(() => task2()) .then(() => task3()) .catch(error => console.error(error));
C. task1() .then(result1 => task2(result1)) .catch(error => console.error(error)) .then(result2 => task3(result2));
D. task1() .catch(error => console.error(error)) .then(result1 => task2(result1)) .then(result2 => task3(result2));

Solution

  1. Step 1: Understand dependency and error handling

    Each task depends on the previous result, so each then must pass the result to the next task function. A single catch at the end handles all errors.
  2. Step 2: Analyze each option

    task1() .then(result1 => task2(result1)) .then(result2 => task3(result2)) .catch(error => console.error(error)); correctly chains tasks with result passing and one catch at the end. task1() .then(() => task2()) .then(() => task3()) .catch(error => console.error(error)); passes task2 and task3 without arguments, which may fail if they expect parameters. task1() .then(result1 => task2(result1)) .catch(error => console.error(error)) .then(result2 => task3(result2)); places catch too early, breaking the chain. task1() .catch(error => console.error(error)) .then(result1 => task2(result1)) .then(result2 => task3(result2)); places catch before then, so errors in later tasks are not caught.
  3. Final Answer:

    task1().then(result1 => task2(result1)).then(result2 => task3(result2)).catch(error => console.error(error)); -> Option A
  4. Quick Check:

    Chain with single catch at end and pass results [OK]
Hint: Chain with one catch at end, pass results explicitly [OK]
Common Mistakes:
  • Placing catch too early breaking chain
  • Not passing results to dependent tasks
  • Multiple catches causing partial error handling
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard