Callbacks let us run code after something finishes. But if not careful, they can cause confusion or errors.
Callback pitfalls in Javascript
Introduction
Syntax
Javascript
function doSomething(callback) { // do work callback(); } doSomething(() => { // code to run after work });
Callbacks are functions passed as arguments to run later.
They help with tasks that take time, like loading data.
Examples
Javascript
function greet(name, callback) { console.log('Hello ' + name); callback(); } greet('Alice', () => { console.log('Done greeting'); });
Javascript
setTimeout(() => { console.log('Waited 1 second'); }, 1000);
Javascript
function loadData(callback) { // simulate data loading setTimeout(() => { callback('Data loaded'); }, 500); } loadData(message => { console.log(message); });
Sample Program
This simulates fetching user data. If userId is 0, it returns an error via callback. Otherwise, it returns user info. It shows how callbacks handle success and error.
Javascript
function fetchUserData(userId, callback) { setTimeout(() => { if (userId === 0) { callback('Error: User not found', null); } else { callback(null, { id: userId, name: 'User' + userId }); } }, 1000); } fetchUserData(0, (error, data) => { if (error) { console.log(error); } else { console.log('User data:', data); } }); fetchUserData(1, (error, data) => { if (error) { console.log(error); } else { console.log('User data:', data); } });
Important Notes
Callbacks can cause "callback hell" if nested too deep, making code hard to read.
Always handle errors inside callbacks to avoid silent failures.
Use named functions for callbacks to keep code clearer.
Summary
Callbacks run code after a task finishes.
They can cause confusion if nested or errors are not handled.
Write clear callbacks and handle errors to avoid problems.
Practice
1. What is a common problem when using callbacks in JavaScript?
easy
Solution
Step 1: Understand what callbacks do
Callbacks run code after a task finishes, often asynchronously.Step 2: Identify common issues with callbacks
Nested callbacks can create complex, hard-to-read code called "callback hell".Final Answer:
Callbacks can cause nested code that is hard to read -> Option BQuick Check:
Callback nesting = hard to read [OK]
Hint: Remember: deep nesting means confusing callbacks [OK]
Common Mistakes:
- Thinking callbacks always run immediately
- Assuming callbacks fix errors automatically
- Believing callbacks speed up code by default
2. Which of the following is the correct syntax to pass a callback function in JavaScript?
easy
Solution
Step 1: Understand how to pass functions as callbacks
Callbacks are passed as function references without parentheses.Step 2: Check each option's syntax
doTask(callback); passes the function reference correctly. doTask(callback()); calls the function immediately, which is wrong.Final Answer:
doTask(callback); -> Option AQuick Check:
Pass function reference without () [OK]
Hint: Pass callback without parentheses to avoid immediate call [OK]
Common Mistakes:
- Calling the callback immediately by adding ()
- Using assignment instead of passing function
- Using invalid syntax like ->
3. What will be the output of this code?
function fetchData(callback) {
setTimeout(() => {
callback('Data loaded');
}, 100);
}
fetchData((message) => {
console.log(message);
});
console.log('Fetching...');medium
Solution
Step 1: Understand asynchronous behavior of setTimeout
setTimeout delays the callback, so 'Fetching...' logs first.Step 2: Trace the order of console.log calls
'Fetching...' prints immediately, then after 100ms 'Data loaded' prints.Final Answer:
Fetching...\nData loaded -> Option CQuick Check:
Async logs: Fetching first, then Data loaded [OK]
Hint: Async callbacks run after current code finishes [OK]
Common Mistakes:
- Assuming callback runs immediately
- Confusing order of console logs
- Ignoring asynchronous delay
4. Identify the error in this callback usage:
function getData(callback) {
let data = null;
callback(data);
}
getData((result) => {
console.log(result.length);
});medium
Solution
Step 1: Check what value is passed to callback
Callback receives null as data, which has no length property.Step 2: Understand why accessing length causes error
Trying to read null.length throws a TypeError.Final Answer:
Calling callback with null causes error accessing length -> Option AQuick Check:
Null has no length property [OK]
Hint: Check callback data type before accessing properties [OK]
Common Mistakes:
- Ignoring null and assuming safe property access
- Confusing callback syntax with function call
- Thinking return is needed instead of callback
5. You want to run two asynchronous tasks in sequence using callbacks. Which pattern avoids callback hell and handles errors properly?
function task1(cb) {
setTimeout(() => cb(null, 'Result1'), 100);
}
function task2(cb) {
setTimeout(() => cb(null, 'Result2'), 100);
}Choose the best way to run task1 then task2 with error handling.hard
Solution
Step 1: Understand sequential callback execution with error checks
Run task1, check error, then run task2 inside task1's callback with error check.Step 2: Analyze each option for error handling and sequence
task1((err, res1) => { if (err) throw err; task2((err, res2) => { if (err) throw err; console.log(res1, res2); }); }); properly sequences tasks and handles errors. Others miss error checks or sequence.Final Answer:
task1((err, res1) => { if (err) throw err; task2((err, res2) => { if (err) throw err; console.log(res1, res2); }); }); -> Option DQuick Check:
Sequence + error handling = nested callbacks with checks [OK]
Hint: Check errors before next callback to avoid silent failures [OK]
Common Mistakes:
- Ignoring errors in callbacks
- Running tasks in parallel instead of sequence
- Passing wrong arguments to callbacks
Recommended
Ready to prove it?
Pass the test and this pattern moves unknown
10 questions ~5 mineasy hard
