Promise chaining is a way to run multiple asynchronous tasks one after another, where each task starts when the previous one finishes, using .then() methods.
Click to reveal answer
beginner
How do you return a value from one promise to the next in a chain?
You return the value inside the .then() callback. This value becomes the input for the next .then() in the chain.
Click to reveal answer
intermediate
What happens if you return a new promise inside a .then() callback?
The next .then() waits for that new promise to resolve before running, allowing you to chain asynchronous operations smoothly.
Click to reveal answer
beginner
How do you handle errors in a promise chain?
You can add a .catch() at the end of the chain to catch any error from any promise in the chain.
Click to reveal answer
beginner
What is the benefit of promise chaining over nested callbacks?
Promise chaining avoids deeply nested code (callback hell), making asynchronous code easier to read and maintain.
Click to reveal answer
What does promise.then() return?
AUndefined
BThe resolved value immediately
CThe original promise
DA new promise
✗ Incorrect
then() always returns a new promise that resolves with the value returned inside its callback.
How can you pass data from one promise to the next in a chain?
ABy using global variables
BBy returning the data inside <code>.then()</code>
CBy calling <code>resolve()</code> manually
DBy using <code>setTimeout()</code>
✗ Incorrect
Returning data inside .then() passes it to the next .then() callback.
What happens if a promise in the chain rejects and there is no .catch()?
AThe chain stops and error is unhandled
BThe error is ignored
CThe next <code>.then()</code> runs anyway
DThe promise resolves with undefined
✗ Incorrect
Without .catch(), a rejection causes an unhandled promise rejection error and stops the chain.
Which of these is a correct way to chain promises?
Returning a promise inside .then() correctly chains the promises.
Why is promise chaining preferred over nested callbacks?
AIt uses less memory
BIt runs faster
CIt makes code shorter and easier to read
DIt avoids using functions
✗ Incorrect
Promise chaining avoids nested code, making asynchronous flows clearer and easier to maintain.
Explain how promise chaining works and why it is useful.
Think about how you can do one task after another without nesting functions.
You got /5 concepts.
Describe how errors are handled in a promise chain.
Consider what happens if something goes wrong in any step.
You got /4 concepts.
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
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 C
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
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.
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.
Final Answer:
p1.then(() => p2).then(result => console.log(result)); -> Option B
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
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
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.
Step 2: Analyze catch placement and behavior
The catch at the end catches any error thrown in previous then callbacks, including synchronous throws.
Final Answer:
Error is caught by catch because thrown inside then chain -> Option A
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?
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.
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 A
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 unknownstrongwhile earning +1 Grip toward your certificate.