Bird
Raised Fist0
Javascriptprogramming~15 mins

Then and catch methods in Javascript - Deep Dive

Choose your learning style10 modes available
Overview - Then and catch methods
What is it?
Then and catch are methods used with Promises in JavaScript to handle asynchronous operations. The then method runs code when a Promise finishes successfully, while catch runs code if the Promise fails. They help manage tasks that take time, like loading data from the internet, without stopping the rest of the program.
Why it matters
Without then and catch, handling tasks that take time would be messy and confusing, making programs freeze or behave unpredictably. These methods let programs keep running smoothly while waiting for results, improving user experience and reliability. They make it easier to write clear, organized code for things that happen later.
Where it fits
Before learning then and catch, you should understand basic JavaScript functions and how asynchronous code works. After mastering these methods, you can learn about async/await syntax, which builds on Promises for even cleaner asynchronous code.
Mental Model
Core Idea
Then runs code after a successful task, catch runs code if the task fails, both helping manage what happens next in asynchronous operations.
Think of it like...
Imagine ordering food at a restaurant: then is like the waiter bringing your meal when it's ready, and catch is like the waiter telling you if the kitchen ran out of your order.
Promise
  │
  ├─ then(successHandler) ──▶ Runs if task succeeds
  │
  └─ catch(errorHandler) ──▶ Runs if task fails
Build-Up - 7 Steps
1
FoundationUnderstanding Promises Basics
🤔
Concept: Introduce what a Promise is and why it is used.
A Promise is a JavaScript object that represents a task that will finish in the future. It can either succeed (resolve) or fail (reject). Promises help avoid waiting and freezing by letting code run while the task is still working.
Result
You know that Promises are placeholders for future results, not immediate values.
Understanding Promises is key because then and catch only work with these objects to handle future outcomes.
2
FoundationBasic Then Method Usage
🤔
Concept: Learn how to use then to handle successful Promise results.
The then method takes a function that runs when the Promise resolves successfully. This function receives the result of the Promise. For example: const promise = Promise.resolve('Hello'); promise.then(result => console.log(result)); This prints 'Hello' when the Promise finishes.
Result
The console shows: Hello
Knowing then lets you react to success without blocking the program, making asynchronous code easier to manage.
3
IntermediateUsing Catch for Errors
🤔
Concept: Learn how catch handles Promise failures.
The catch method takes a function that runs if the Promise rejects with an error. For example: const promise = Promise.reject('Error happened'); promise.catch(error => console.log(error)); This prints the error message when the Promise fails.
Result
The console shows: Error happened
Using catch prevents unhandled errors and keeps your program from crashing unexpectedly.
4
IntermediateChaining Then and Catch Methods
🤔Before reading on: Do you think catch can handle errors from any previous then in the chain? Commit to your answer.
Concept: Learn how to chain multiple then calls and add catch at the end to handle errors anywhere in the chain.
Promises can chain then methods to run steps in order. If any step fails, catch at the end catches the error: Promise.resolve(5) .then(num => num * 2) .then(num => { throw 'Oops'; }) .catch(error => console.log('Caught:', error)); This prints 'Caught: Oops'.
Result
The console shows: Caught: Oops
Knowing catch handles errors from any previous step helps write safer, cleaner asynchronous code.
5
IntermediateReturning Promises in Then
🤔Before reading on: If a then returns a Promise, does the next then wait for it to finish? Commit to your answer.
Concept: Understand that returning a Promise inside then creates a chain that waits for that Promise to resolve before continuing.
If a then returns a Promise, the next then waits for it: Promise.resolve(10) .then(num => Promise.resolve(num + 5)) .then(result => console.log(result)); This prints 15 after the inner Promise resolves.
Result
The console shows: 15
Understanding this chaining behavior is crucial for sequencing asynchronous tasks correctly.
6
AdvancedError Propagation in Then Chains
🤔Before reading on: If a then throws an error, will catch always catch it? Commit to your answer.
Concept: Learn how errors thrown inside then propagate down the chain until caught by catch.
Errors thrown inside then skip all following then methods until a catch is found: Promise.resolve() .then(() => { throw 'Error in then'; }) .then(() => console.log('This will not run')) .catch(error => console.log('Caught:', error)); Only the catch runs, printing the error.
Result
The console shows: Caught: Error in then
Knowing error propagation prevents silent failures and helps design robust asynchronous flows.
7
ExpertSubtle Differences Between Catch and Then
🤔Before reading on: Can then handle errors if you provide a second function? Is it the same as catch? Commit to your answer.
Concept: Explore how then can take two functions (success and failure), but catch is preferred for error handling due to clearer semantics and chaining behavior.
Then can take two arguments: Promise.reject('Fail') .then( result => console.log('Success:', result), error => console.log('Handled in then:', error) ); But catch is clearer and better for chaining: Promise.reject('Fail') .catch(error => console.log('Handled in catch:', error));
Result
Both print the error, but catch is more readable and chains better.
Understanding this subtlety helps write clearer, more maintainable asynchronous code.
Under the Hood
Promises represent a future value with three states: pending, fulfilled, or rejected. Then and catch register callback functions that the JavaScript engine stores internally. When the Promise settles (fulfills or rejects), the engine runs the appropriate callbacks asynchronously in the microtask queue, ensuring the main program flow is not blocked.
Why designed this way?
Promises and their then/catch methods were designed to replace older callback patterns that caused confusing nested code ('callback hell'). This design allows chaining and centralized error handling, making asynchronous code easier to write and reason about.
┌─────────────┐
│  Promise    │
│ (pending)  │
└─────┬───────┘
      │
      ▼
┌─────────────┐       ┌─────────────┐
│ fulfilled   │──────▶│ then(success)│
└─────────────┘       └─────────────┘
      │
      ▼
┌─────────────┐       ┌─────────────┐
│ rejected    │──────▶│ catch(error) │
└─────────────┘       └─────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does catch only handle errors from the Promise itself, or also from previous then methods? Commit to your answer.
Common Belief:Catch only handles errors from the original Promise rejection, not from errors thrown inside then methods.
Tap to reveal reality
Reality:Catch handles any error thrown in the Promise chain, including inside then methods.
Why it matters:Believing otherwise can cause missed errors and bugs that are hard to find.
Quick: If you don't add catch, will errors in Promises be ignored silently? Commit to your answer.
Common Belief:If you omit catch, errors in Promises are ignored and don't affect the program.
Tap to reveal reality
Reality:Without catch, unhandled Promise rejections cause warnings and can crash the program in some environments.
Why it matters:Ignoring errors leads to unstable programs and poor user experience.
Quick: Can then handle both success and failure equally well? Commit to your answer.
Common Belief:Then can handle both success and failure by passing two functions as arguments, so catch is unnecessary.
Tap to reveal reality
Reality:While then can take two functions, catch is clearer and better for error handling and chaining.
Why it matters:Using then for errors can make code harder to read and maintain.
Quick: Does returning a value inside then immediately run the next then? Commit to your answer.
Common Belief:Returning a value inside then runs the next then immediately, without waiting.
Tap to reveal reality
Reality:Returning a Promise inside then delays the next then until that Promise resolves.
Why it matters:Misunderstanding this causes bugs in sequencing asynchronous tasks.
Expert Zone
1
Errors thrown inside catch handlers propagate down the chain just like in then, so you can chain multiple catch blocks for different error handling.
2
Then and catch always run asynchronously, even if the Promise is already settled, ensuring consistent timing and avoiding unexpected behavior.
3
Using catch at the end of a chain is a best practice to centralize error handling, but intermediate catch blocks can be used to recover and continue the chain.
When NOT to use
Then and catch are less readable for complex asynchronous flows compared to async/await syntax, which uses try/catch blocks and looks more like synchronous code. For very simple callbacks, direct callback functions might be simpler.
Production Patterns
In real-world code, then and catch are used to handle API calls, file operations, and timers. Developers often chain multiple then calls for sequential steps and use catch at the end to handle any errors. They also combine then/catch with Promise.all for parallel tasks.
Connections
Async/Await
Builds-on
Understanding then and catch is essential because async/await is syntactic sugar over Promises and uses them under the hood.
Error Handling in Synchronous Code
Similar pattern
Catch in Promises is like try/catch in synchronous code, helping learners transfer error handling concepts across asynchronous and synchronous contexts.
Event-driven Programming
Same pattern
Then and catch methods resemble event listeners that respond to future events, connecting asynchronous programming to broader event-driven design.
Common Pitfalls
#1Forgetting to add catch leads to unhandled errors.
Wrong approach:Promise.resolve() .then(() => { throw 'Error'; });
Correct approach:Promise.resolve() .then(() => { throw 'Error'; }) .catch(error => console.log(error));
Root cause:Not understanding that errors in then must be caught explicitly to avoid unhandled rejections.
#2Using then with two arguments instead of catch for errors reduces code clarity.
Wrong approach:Promise.reject('Fail') .then( result => console.log(result), error => console.log('Error:', error) );
Correct approach:Promise.reject('Fail') .catch(error => console.log('Error:', error));
Root cause:Confusing error handling options and not following best practices for readability.
#3Returning a non-Promise value inside then when a Promise is expected causes timing bugs.
Wrong approach:Promise.resolve(5) .then(num => num + 1) .then(result => console.log(result));
Correct approach:Promise.resolve(5) .then(num => Promise.resolve(num + 1)) .then(result => console.log(result));
Root cause:Not realizing that returning a Promise delays the next then, while returning a value runs it immediately.
Key Takeaways
Then and catch methods let you handle success and failure of asynchronous tasks clearly and in order.
Chaining then calls allows sequencing multiple steps, while catch centralizes error handling for the whole chain.
Errors thrown inside then propagate down the chain until caught, preventing silent failures.
Returning Promises inside then delays the next step until the Promise resolves, enabling complex asynchronous flows.
Using catch instead of then's second argument for errors improves code readability and maintainability.

Practice

(1/5)
1. What does the then method do in JavaScript promises?
easy
A. Creates a new promise
B. Runs when the task fails
C. Stops the promise from running
D. Runs when the task finishes successfully

Solution

  1. Step 1: Understand the role of then

    The then method is used to handle the result when a promise completes successfully.
  2. Step 2: Differentiate from catch

    The catch method handles errors or failures, not success.
  3. Final Answer:

    Runs when the task finishes successfully -> Option D
  4. Quick Check:

    then = success handler [OK]
Hint: Remember: then = success, catch = failure [OK]
Common Mistakes:
  • Confusing then with catch
  • Thinking then stops the promise
  • Believing then creates a new promise
2. Which of the following is the correct syntax to add a catch handler to a promise named p?
easy
A. catch(p, () => console.log('Error'))
B. p.then.catch(() => console.log('Error'))
C. p.catch(() => console.log('Error'))
D. p.catch = () => console.log('Error')

Solution

  1. Step 1: Recall correct catch syntax

    The catch method is called directly on the promise object like p.catch(callback).
  2. Step 2: Check each option

    p.catch(() => console.log('Error')) uses correct syntax. p.then.catch(() => console.log('Error')) chains incorrectly. p.catch = () => console.log('Error') tries to assign catch as a property. catch(p, () => console.log('Error')) uses invalid function call.
  3. Final Answer:

    p.catch(() => console.log('Error')) -> Option C
  4. Quick Check:

    Use promise.catch() syntax [OK]
Hint: Use promise.catch(callback) to handle errors [OK]
Common Mistakes:
  • Chaining catch after then incorrectly
  • Assigning catch as a property
  • Using catch as a standalone function
3. What will be the output of this code?
Promise.resolve('Hello')
  .then(msg => msg + ' World')
  .then(console.log)
  .catch(() => console.log('Error'));
medium
A. Hello
B. Hello World
C. Error
D. undefined

Solution

  1. Step 1: Follow promise resolution

    The promise resolves with 'Hello'. The first then adds ' World' to it, resulting in 'Hello World'.
  2. Step 2: Output from second then

    The second then logs the result 'Hello World'. The catch is not called because no error occurs.
  3. Final Answer:

    Hello World -> Option B
  4. Quick Check:

    Promise resolves + then chains = 'Hello World' [OK]
Hint: then chains transform and pass values forward [OK]
Common Mistakes:
  • Expecting catch to run without error
  • Ignoring value returned by first then
  • Thinking console.log returns undefined
4. Identify the error in this code snippet:
fetch('url')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.log('Error:', error));

fetch('url')
  .then(response => response.json())
  .catch(error => console.log('Error:', error))
  .then(data => console.log(data));
medium
A. The second chain logs data even if fetch fails
B. The first chain has wrong catch placement
C. Both chains are correct
D. fetch cannot be chained with then and catch

Solution

  1. Step 1: Analyze first chain

    The first chain calls then twice and catch last, so errors are caught properly.
  2. Step 2: Analyze second chain

    The second chain calls catch before the last then. So even if fetch fails, the last then runs with undefined data, causing possible issues.
  3. Final Answer:

    The second chain logs data even if fetch fails -> Option A
  4. Quick Check:

    Catch before then can cause unexpected data [OK]
Hint: Place catch last to handle errors before then [OK]
Common Mistakes:
  • Placing catch before then incorrectly
  • Assuming catch stops later then calls
  • Ignoring promise chain order
5. You want to fetch user data and then fetch their posts only if the user fetch succeeds. Which code correctly uses then and catch to do this?
hard
A. fetchUser() .then(user => fetchPosts(user.id)) .then(posts => console.log(posts)) .catch(err => console.log('Error:', err));
B. fetchUser() .catch(err => console.log('Error:', err)) .then(user => fetchPosts(user.id)) .then(posts => console.log(posts));
C. fetchUser() .then(user => fetchPosts(user.id)) .catch(err => console.log('Error:', err)) .then(posts => console.log(posts));
D. fetchUser() .then(user => fetchPosts(user.id)) .catch(err => console.log('Error:', err)) .catch(err => console.log('Another error:', err));

Solution

  1. Step 1: Understand chaining for dependent tasks

    We want to fetch posts only if user fetch succeeds, so fetchPosts must be inside the first then.
  2. Step 2: Place catch at the end

    Catch should be last to handle any error from either fetchUser or fetchPosts.
  3. Final Answer:

    fetchUser().then(user => fetchPosts(user.id)).then(posts => console.log(posts)).catch(err => console.log('Error:', err)); -> Option A
  4. Quick Check:

    Chain then for success, catch last for errors [OK]
Hint: Chain dependent tasks in then, catch errors last [OK]
Common Mistakes:
  • Placing catch before all then calls
  • Calling then after catch causing unexpected runs
  • Using multiple catch handlers unnecessarily
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