Pass an Operation to Another Function
Pass an Operation to Another Function
A callback is a function supplied for another operation to call. Not every callback is asynchronous: map calls this callback while building its result before the next statement runs.
Before this topic, review Match a Simple Text Pattern if its terms are unfamiliar.
What you’ll learn
- Explain pass an operation to another function through the school example.
- Trace the shown operations and distinguish their result from displayed output.
- Make the practice change and explain its consequence: map applies the edited correction synchronously to each value.
Work through the school example
This is JavaScript using language features and the host console. Read the initial values, then follow each operation to its displayed result. A declaration names a value, a function call performs an operation, and console.log displays its arguments.
JavaScript · school.js · complete example
const marks = [70, 80];
console.log(marks.map((mark) => mark + 2).join(","));
console.log("Report ready");
Expected output
72,82
Report readyRun in JavaScript compiler →Understanding Callbacks in JavaScript
JavaScript is single-threaded and often performs asynchronous operations like API calls, timers, or file reading. To handle such operations without blocking the main thread, callbacks are used.
What is a Callback?
A callback is a function passed as an argument to another function, which is then invoked inside that function after some operation is complete.
Example: Basic Callback Function
function greetUser(name, callback) {
console.log("Hello " + name);
callback();
}
function sayBye() {
console.log("Goodbye!");
}
greetUser("Alice", sayBye);
Hello Alice Goodbye!
Why are Callbacks Important?
JavaScript executes code line by line, but asynchronous operations (like network requests) don’t complete instantly. Callbacks ensure that a task runs only after the previous one finishes.
Example: Simulating Asynchronous Execution
function fetchData(callback) {
setTimeout(() => {
console.log("Data fetched from server.");
callback();
}, 2000);
}
function processData() {
console.log("Processing data...");
}
fetchData(processData);
Data fetched from server. Processing data...
What if we have multiple steps depending on each other?
Let’s simulate a real-world example: logging in, fetching user profile, then fetching posts.
Example: Nested Callbacks
function loginUser(callback) {
setTimeout(() => {
console.log("User logged in");
callback();
}, 1000);
}
function fetchProfile(callback) {
setTimeout(() => {
console.log("User profile fetched");
callback();
}, 1000);
}
function fetchPosts() {
setTimeout(() => {
console.log("User posts fetched");
}, 1000);
}
loginUser(() => {
fetchProfile(() => {
fetchPosts();
});
});
User logged in User profile fetched User posts fetched
What is Callback Hell?
When multiple asynchronous operations are nested within each other in this way, it creates deeply nested code that is hard to read, debug, and maintain. This is known as Callback Hell or the “Pyramid of Doom”.
Callback hell makes the code look like this:
task1(() => {
task2(() => {
task3(() => {
task4(() => {
// and so on...
});
});
});
});
Question: Why not just call functions sequentially?
Answer: Because functions like setTimeout or fetch are asynchronous. If you don’t use callbacks (or promises), the next function might execute before the previous one finishes.
How to Avoid Callback Hell?
Solutions include:
- Splitting functions into smaller named functions
- Using Promises
- Using async/await
We will explore Promises and async/await in upcoming modules to resolve this issue effectively.
Summary
- Callbacks are functions passed to another function to execute later.
- They are essential in handling asynchronous code in JavaScript.
- Nested callbacks lead to callback hell — hard-to-maintain code structure.
- Modern JavaScript uses Promises and async/await for cleaner asynchronous code.
Recognize the important boundary
Nested asynchronous callbacks can obscure sequencing and errors. Using a callback alone does not put work into a background thread.
Try a small variation
JavaScript · original source for practice
const marks = [70, 80];
console.log(marks.map((mark) => mark + 2).join(","));
console.log("Report ready");
Your task: Replace mark + 2 with mark + 3. Predict the result before running the edited program.
The source is repeated here. If the edit targets the HTML rather than the script, use the markup repeated below; the worked answer also repeats the changed markup.
Worked answer and reasoning
map applies the edited correction synchronously to each value.
JavaScript · complete worked variation
const marks = [70, 80];
console.log(marks.map((mark) => mark + 3).join(","));
console.log("Report ready");
Expected output
73,83
Report readyRun in JavaScript compiler →Predict the original program
JavaScript · original program for this question
const marks = [70, 80];
console.log(marks.map((mark) => mark + 2).join(","));
console.log("Report ready");
Keep the useful idea
A callback is a function supplied for another operation to call. Not every callback is asynchronous: map calls this callback while building its result before the next statement runs.
Check your variation against this explanation: map applies the edited correction synchronously to each value.
Use the JavaScript array reference library for individual array operations and boundary tests to check a rule independently.
Reaching the recap and completing the quizzes are separate milestones.