How to Use Callback Functions in JavaScript
Use callback functions when one function should run after another function finishes or when behavior should be passed in as reusable logic. Callbacks are common in array methods, timers, event handlers, and async flows.
What you’ll build or solve
You’ll learn how to use callback functions in JavaScript by passing one function into another. You’ll also know how callbacks improve reuse and sequencing.
Learn JavaScript on Mimo
When this approach works best
This approach is the right choice when the next action depends on a previous function call.
Common real-world scenarios include:
- Array methods
- Timers
- Button click handlers
- API response handlers
- Custom reusable utilities
This is a bad idea when the flow becomes deeply nested. In that case, promises or async/await are usually cleaner.
Prerequisites
You only need:
- A JavaScript file or browser console
- Basic functions knowledge
Step-by-step instructions
Step 1: Pass a function as an argument and call it later
Create a function that accepts another function as a parameter.
JavaScript
function processUser(name, callback) {
const message = `Hello, ${name}`;
callback(message);
}
Then pass a callback when calling it.
JavaScript
processUser("Alex", function (message) {
console.log(message);
});
Arrow functions work especially well for short callbacks.
JavaScript
processUser("Mia", (message) => {
console.log(message);
});
What to look for:
- Pass the function reference, not the result
- Call the callback inside the parent function
- Great for sequencing actions
- Common in timers and array methods
- Arrow functions keep callback code shorter
Examples you can copy
Array callback
JavaScript
const numbers = [1, 2, 3];
numbers.forEach((num) => {
console.log(num);
});
Timer callback
JavaScript
setTimeout(() => {
console.log("Done");
}, 1000);
Reusable logger
JavaScript
function runTask(callback) {
callback();
}
Common mistakes and how to fix them
Mistake 1: Calling the callback too early
What the reader might do:
JavaScript
processUser("Alex", console.log());
Why it breaks: console.log() runs immediately, and its result gets passed instead of the function.
Corrected approach:
JavaScript
processUser("Alex", console.log);
Or wrap it.
JavaScript
processUser("Alex", (message) => console.log(message));
Mistake 2: Forgetting to call the callback inside the function
What the reader might do:
JavaScript
function runTask(callback) {
callback;
}
Why it breaks: the callback is referenced but never executed.
Corrected approach:
JavaScript
function runTask(callback) {
callback();
}
Mistake 3: Deep nested callback chains
What the reader might do:
JavaScript
task1(() => {
task2(() => {
task3(() => {});
});
});
Why it breaks: deeply nested callbacks quickly become hard to read.
Corrected approach:
Refactor to promises or split callbacks into named functions.
Troubleshooting
If the callback runs immediately, pass the function reference instead of calling it.
If nothing happens, check whether the callback is actually invoked.
If nested callbacks become messy, switch to promises or async/await.
If callback arguments are missing, verify the parent function passes them in.
Quick recap
- Pass functions as arguments
- Call them later inside another function
- Great for sequencing and reuse
- Pass the function reference, not the result
- Use promises when nesting gets too deep
Join 35M+ people learning for free on Mimo
4.8 out of 5 across 1M+ reviews
Check us out on Apple AppStore, Google Play Store, and Trustpilot