Promise chaining helps you run tasks one after another in order. It makes sure each step waits for the previous one to finish.
Promise chaining in Javascript
const promise = new Promise((resolve, reject) => { // do something async resolve(value); }); promise .then(result => { // handle result return nextValue; }) .then(nextResult => { // handle next result }) .catch(error => { // handle any error from above });
Each then returns a new promise, so you can chain many.
If a then returns a value, it becomes the input for the next then.
Promise.resolve(5) .then(value => value * 2) .then(value => console.log(value));
then are caught by catch.Promise.resolve() .then(() => { throw new Error('Oops'); }) .catch(error => console.log(error.message));
then calls passing values along.Promise.resolve('start') .then(value => { console.log(value); return 'next'; }) .then(value => console.log(value));
This program gets a number asynchronously, then changes it step by step using promise chaining. Each step waits for the previous one.
function fetchNumber() { return new Promise((resolve) => { setTimeout(() => resolve(10), 500); }); } fetchNumber() .then(number => { console.log('First number:', number); return number * 3; }) .then(newNumber => { console.log('After multiplying by 3:', newNumber); return newNumber - 5; }) .then(finalNumber => { console.log('After subtracting 5:', finalNumber); }) .catch(error => { console.error('Error:', error); });
Time complexity depends on the tasks inside each then, but chaining itself is fast.
Space complexity is low since promises handle state internally.
Common mistake: forgetting to return a value inside then causes the next then to get undefined.
Use promise chaining when you want clear, step-by-step async code instead of nested callbacks.
Promise chaining runs async tasks in order, passing results along.
Each then returns a new promise, allowing many steps.
Errors anywhere in the chain can be caught with a single catch.
Practice
Solution
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.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.Final Answer:
Run asynchronous tasks one after another, passing results along -> Option CQuick Check:
Promise chaining = sequential async tasks [OK]
- Thinking promises run synchronously
- Believing chaining stops tasks immediately
- Confusing promise chaining with parallel execution
p1 and p2?Solution
Step 1: Understand promise chaining syntax
To chain promises, the first promise'sthenshould return the second promise function call, so it waits for it.Step 2: Analyze each option
p1.then(() => p2).then(result => console.log(result)); correctly returnsp2insidethen. p1.then(p2).then(result => console.log(result)); passesp2directly, which is incorrect. p1.then().then(p2).then(result => console.log(result)); has an emptythen()which is invalid. p1.then(result => p2).catch(console.log); usescatchprematurely and returnsp2incorrectly.Final Answer:
p1.then(() => p2).then(result => console.log(result)); -> Option BQuick Check:
Return next promise in then = correct chaining [OK]
- Passing promise directly to then instead of a function
- Leaving then() empty
- Misplacing catch before chain ends
Promise.resolve(5) .then(x => x * 2) .then(x => Promise.resolve(x + 3)) .then(console.log);
Solution
Step 1: Trace each then step
First,Promise.resolve(5)resolves with 5. Thenx => x * 2returns 10. Next,x => Promise.resolve(x + 3)returns a promise resolving to 13.Step 2: Understand final then output
The lastthen(console.log)logs the resolved value 13, not a promise object.Final Answer:
13 -> Option DQuick Check:
Promise chaining unwraps nested promises [OK]
- Thinking console.log prints a Promise object
- Ignoring that then unwraps promises
- Confusing multiplication and addition order
fetchData()
.then(data => processData(data))
.then(result => console.log(result))
.catch(error => console.error(error));
function processData(data) {
throw new Error('Processing failed');
}Solution
Step 1: Understand error throwing in promise chain
Throwing an error insideprocessDatacauses the promise to reject, which is caught by thecatchat the end.Step 2: Analyze catch placement and behavior
Thecatchat the end catches any error thrown in previousthencallbacks, including synchronous throws.Final Answer:
Error is caught by catch because thrown inside then chain -> Option AQuick Check:
Thrown errors in then are caught by catch [OK]
- Thinking synchronous errors are not caught
- Placing catch before then incorrectly
- Assuming missing return causes error
task1, task2, and task3 in order, where each depends on the previous result. Which code correctly chains them and catches any error once?Solution
Step 1: Understand dependency and error handling
Each task depends on the previous result, so eachthenmust pass the result to the next task function. A singlecatchat the end handles all errors.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.Final Answer:
task1().then(result1 => task2(result1)).then(result2 => task3(result2)).catch(error => console.error(error)); -> Option AQuick Check:
Chain with single catch at end and pass results [OK]
- Placing catch too early breaking chain
- Not passing results to dependent tasks
- Multiple catches causing partial error handling
Ready to prove it?
Pass the test and this pattern moves unknown
