Bird
Raised Fist0
Node.jsframework~20 mins

Callback pattern and callback hell in Node.js - Practice Problems & Coding Challenges

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
Challenge - 5 Problems
🎖️
Callback Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
Understanding callback execution order
Consider the following Node.js code using callbacks. What will be the order of console output?
Node.js
function first(callback) {
  console.log('first');
  callback();
}

function second(callback) {
  setTimeout(() => {
    console.log('second');
    callback();
  }, 0);
}

function third() {
  console.log('third');
}

first(() => {
  second(() => {
    third();
  });
});
A"first", "third", "second"
B"first", "second", "third"
C"second", "first", "third"
D"third", "first", "second"
Attempts:
2 left
💡 Hint
Remember that setTimeout with 0 delay runs after the current call stack.
📝 Syntax
intermediate
2:00remaining
Identify the syntax error in callback usage
Which option contains a syntax error that will prevent the code from running?
Node.js
function fetchData(callback) {
  setTimeout(() => {
    callback(null, 'data');
  }, 100);
}

fetchData((err, data) => {
  if (err) {
    console.error(err);
  } else {
    console.log(data);
  }
});
AfetchData((err, data) => { if (err) { console.error(err); } else { console.log(data); } });
B;)} } ;)atad(gol.elosnoc { esle } ;)rre(rorre.elosnoc { )rre( fi { >= )atad ,rre((ataDhctef
CfetchData(function(err, data) { if (err) { console.error(err); } else { console.log(data); } });
D;)} } ;)atad(gol.elosnoc { esle } ;)rre(rorre.elosnoc { )rre( fi { )atad ,rre(noitcnuf(ataDhctef
Attempts:
2 left
💡 Hint
Look carefully at the if-else statement syntax.
🔧 Debug
advanced
2:00remaining
Debugging callback hell with nested callbacks
What is the main problem with the following code snippet?
Node.js
function step1(callback) {
  setTimeout(() => {
    console.log('step1 done');
    callback();
  }, 100);
}

function step2(callback) {
  setTimeout(() => {
    console.log('step2 done');
    callback();
  }, 100);
}

function step3(callback) {
  setTimeout(() => {
    console.log('step3 done');
    callback();
  }, 100);
}

step1(() => {
  step2(() => {
    step3(() => {
      console.log('All steps done');
    });
  });
});
AThe setTimeout delays are too long causing performance issues.
BThe callbacks are not called, so the code never runs.
CThe code causes callback hell making it hard to read and maintain.
DThe code will throw a runtime error due to missing callback arguments.
Attempts:
2 left
💡 Hint
Look at how callbacks are nested inside each other.
state_output
advanced
2:00remaining
What is the output of nested callbacks with error handling?
Given the code below, what will be printed to the console?
Node.js
function task1(callback) {
  setTimeout(() => {
    callback(null, 'result1');
  }, 50);
}

function task2(callback) {
  setTimeout(() => {
    callback('error in task2');
  }, 50);
}

task1((err, res) => {
  if (err) {
    console.log('Error:', err);
  } else {
    console.log(res);
    task2((err2, res2) => {
      if (err2) {
        console.log('Error:', err2);
      } else {
        console.log(res2);
      }
    });
  }
});
A"result1" followed by "Error: error in task2"
B"result1" followed by "undefined"
C"Error: error in task2" followed by "result1"
DNo output due to uncaught error
Attempts:
2 left
💡 Hint
Check how errors are handled in each callback.
🧠 Conceptual
expert
2:00remaining
Why does callback hell occur and how to avoid it?
Which option best explains why callback hell happens and a common way to avoid it in Node.js?
ACallback hell happens because callbacks run too fast; adding delays fixes it.
BCallback hell happens because callbacks are not typed; using TypeScript solves it.
CCallback hell happens because callbacks are synchronous; making them asynchronous avoids it.
DCallback hell happens because callbacks are nested deeply; using Promises or async/await helps flatten the code.
Attempts:
2 left
💡 Hint
Think about code readability and modern JavaScript features.

Practice

(1/5)
1. What is the main purpose of a callback function in Node.js?
easy
A. To run code after an asynchronous action finishes
B. To stop the program execution immediately
C. To create a new thread for parallel processing
D. To convert synchronous code into asynchronous code automatically

Solution

  1. Step 1: Understand asynchronous actions in Node.js

    Node.js uses callbacks to handle tasks that take time, like reading files or fetching data, without stopping the program.
  2. Step 2: Identify the role of the callback

    The callback function runs after the task finishes, allowing the program to continue smoothly.
  3. Final Answer:

    To run code after an asynchronous action finishes -> Option A
  4. Quick Check:

    Callback = run after async task [OK]
Hint: Callbacks run code after tasks finish [OK]
Common Mistakes:
  • Thinking callbacks stop program execution
  • Confusing callbacks with threads
  • Assuming callbacks convert sync to async automatically
2. Which of the following is the correct function declaration syntax to define a callback function in Node.js?
easy
A. function callback { console.log('Done'); }
B. callback => { console.log('Done'); }
C. function callback() { console.log('Done'); }
D. callback() => { console.log('Done'); }

Solution

  1. Step 1: Review function declaration syntax

    In JavaScript, a function is declared with the keyword 'function' followed by parentheses and curly braces.
  2. Step 2: Check each option for syntax correctness

    function callback() { console.log('Done'); } uses correct syntax. callback => { console.log('Done'); } is an arrow function expression, not a function declaration. function callback { console.log('Done'); } misses parentheses after function name. callback() => { console.log('Done'); } mixes arrow function and parentheses incorrectly.
  3. Final Answer:

    function callback() { console.log('Done'); } -> Option C
  4. Quick Check:

    Correct function syntax = function callback() { console.log('Done'); } [OK]
Hint: Function syntax: function name() { } [OK]
Common Mistakes:
  • Omitting parentheses in function declaration
  • Mixing arrow function syntax incorrectly
  • Missing curly braces for function body
3. What will be the output of the following code?
function first(callback) {
  setTimeout(() => {
    console.log('First');
    callback();
  }, 100);
}

function second() {
  console.log('Second');
}

first(second);
medium
A. First\nSecond
B. Second\nFirst
C. First
D. Second

Solution

  1. Step 1: Understand setTimeout behavior

    setTimeout delays the function inside it by 100 milliseconds, then runs the callback.
  2. Step 2: Trace the code execution order

    first() calls setTimeout, which waits 100ms, then logs 'First' and calls second(). So 'First' prints first, then 'Second'.
  3. Final Answer:

    First\nSecond -> Option A
  4. Quick Check:

    Callback runs after delay = 'First' then 'Second' [OK]
Hint: setTimeout delays code, callback runs after delay [OK]
Common Mistakes:
  • Assuming callback runs immediately
  • Confusing order of console logs
  • Ignoring asynchronous delay
4. Identify the problem in this nested callback code and how to fix it:
readFile('file1.txt', function(err, data1) {
  if (err) throw err;
  readFile('file2.txt', function(err, data2) {
    if (err) throw err;
    readFile('file3.txt', function(err, data3) {
      if (err) throw err;
      console.log(data1, data2, data3);
    });
  });
});
medium
A. Use synchronous readFileSync to avoid callbacks
B. This is callback hell; fix by using Promises or async/await
C. Syntax error: missing semicolons after callbacks
D. No problem; this is the best way to read files sequentially

Solution

  1. Step 1: Recognize nested callbacks cause callback hell

    Multiple nested callbacks make code hard to read and maintain, known as callback hell.
  2. Step 2: Suggest modern alternatives

    Using Promises or async/await flattens the code, making it cleaner and easier to follow.
  3. Final Answer:

    This is callback hell; fix by using Promises or async/await -> Option B
  4. Quick Check:

    Nested callbacks = callback hell, use Promises [OK]
Hint: Nested callbacks = callback hell; use Promises [OK]
Common Mistakes:
  • Ignoring readability problems
  • Thinking semicolons fix callback hell
  • Using synchronous calls in async code
5. You have three asynchronous tasks that depend on each other in sequence. Which approach best avoids callback hell while keeping the tasks in order?
hard
A. Use nested callbacks for each task
B. Use setTimeout to delay each task manually
C. Run all tasks in parallel without waiting
D. Use Promises chaining or async/await syntax

Solution

  1. Step 1: Understand the problem of callback hell

    Nested callbacks make code messy and hard to maintain when tasks depend on each other.
  2. Step 2: Identify better patterns for sequencing async tasks

    Promises chaining or async/await syntax keep code flat and readable while preserving order.
  3. Final Answer:

    Use Promises chaining or async/await syntax -> Option D
  4. Quick Check:

    Promises/async await = clean sequential async code [OK]
Hint: Use Promises or async/await for clean async flow [OK]
Common Mistakes:
  • Using nested callbacks causing callback hell
  • Running tasks in parallel when order matters
  • Using setTimeout for sequencing tasks