JavaScript Callbacks
Functions that call other functions
📞 What are Callbacks?
A callback is a function that is passed as an argument to another function and is executed after (or during) the execution of that function.
// Simple callback example
function greet(name, callback) {
console.log('Hello ' + name);
callback();
}
function sayGoodbye() {
console.log('Goodbye!');
}
greet('John', sayGoodbye);
Output:
Hello John
Goodbye!
Types of Callbacks
Synchronous
Execute immediately
function process(callback) {
callback();
}
Asynchronous
Execute after some time
setTimeout(callback, 1000);
Event Callbacks
Execute on events
button.addEventListener('click', callback);
Array Callbacks
Execute for each element
array.forEach(callback);
🔹 Basic Callback Example
Here's how callbacks work step by step:
// Step 1: Define a function that accepts a callback
function calculate(num1, num2, operation) {
const result = operation(num1, num2);
console.log('Result: ' + result);
return result;
}
// Step 2: Define callback functions
function add(a, b) {
return a + b;
}
function multiply(a, b) {
return a * b;
}
// Step 3: Use the callbacks
calculate(5, 3, add); // Passes add function as callback
calculate(5, 3, multiply); // Passes multiply function as callback
Output:
Result: 8
Result: 15
🔹 Anonymous Callbacks
You can also use anonymous functions as callbacks:
// Using anonymous function as callback
const numbers = [1, 2, 3, 4, 5];
// Anonymous callback with forEach
numbers.forEach(function(number) {
console.log('Number: ' + number);
});
// Arrow function callback
numbers.forEach((number) => {
console.log('Square: ' + (number * number));
});
// Even shorter arrow function
numbers.forEach(num => console.log('Double: ' + (num * 2)));
Output:
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
Square: 1
Square: 4
Square: 9
Square: 16
Square: 25
Double: 2
Double: 4
Double: 6
Double: 8
Double: 10
🔹 Asynchronous Callbacks
Callbacks are commonly used for asynchronous operations:
// Simulating an API call with setTimeout
function fetchUserData(userId, callback) {
console.log('Fetching user data...');
// Simulate network delay
setTimeout(() => {
const userData = {
id: userId,
name: 'John Doe',
email: '[email protected]'
};
// Call the callback with the data
callback(userData);
}, 2000); // 2 second delay
}
// Using the async function
fetchUserData(123, function(user) {
console.log('User data received:');
console.log('Name: ' + user.name);
console.log('Email: ' + user.email);
});
Output:
Fetching user data...
(2 seconds later...)
User data received:
Name: John Doe
Email: [email protected]
🔹 Error Handling with Callbacks
Handle errors in callbacks using the error-first pattern:
function readFile(filename, callback) {
// Simulate file reading
setTimeout(() => {
if (filename === 'nonexistent.txt') {
// Error case - call callback with error as first parameter
callback(new Error('File not found'), null);
} else {
// Success case - call callback with null error and data
callback(null, 'File content here...');
}
}, 1000);
}
// Using error-first callback
readFile('data.txt', function(error, data) {
if (error) {
console.log('Error: ' + error.message);
} else {
console.log('File content: ' + data);
}
});
readFile('nonexistent.txt', function(error, data) {
if (error) {
console.log('Error: ' + error.message);
} else {
console.log('File content: ' + data);
}
});
Output:
File content: File content here...
Error: File not found