Imagine you have a car, and the car breaks down, but this car is really important to you because you need it to go to work the next day. So you call your friend John, John is an auto-repair man, John tows your car to his workshop. But before he leaves, you ask him to call you once he is done with the repairs (again, because the car is so important). John eventually finishes effecting repairs in 2 hours, then calls you.
Introducing JavaScript Callbacks.
Say the above example is a JavaScript program, with repairCar()
being a function within the program which asks John to come tow your car, the instruction issued to him to call you when he is done with the repairs can be likened to a callback. How? because you simply issued a sub instruction to John, asking to be notified when repairs are done.
This callback, is another instruction within an existing instruction, to be carried out after the main instruction. 😅
A callback function is defined as function, say F that is passed to another function, G, causing F to be executed inside G. Nerdy stuff 🤓
Using the example of the default javascript setTimeout()
function, we will examine how callbacks are used. the setTimeout()
function takes two parameters, a callback, and the time (in milliseconds) before the callback is executed.
setTimeout( function(){console.log('callback run')}, 3000 )
the code block above demonstrates the use of a callback within the setTimeout()
function. Analyzing this properly, we can see that only two parameters were passed to the setTimeout()
Function: the callback, and the time in milliseconds.
Yeah, callbacks are very cool and all, but can I define my own functions that need callbacks?
Sure, sure you can. I will jump straight into an example.
function needCallback(parameter, callBackEntry = function(){}){
//perform computation with parammeter one
const result = parameter * 100;
//execute callback function
callBackEntry(result);
}
Let me explain, in the code block above, we simply defined a function that takes two parameters, the second, being a callback function.
Within the body of the function, we performed a computation with the first parameter, and passed its result to the callback function, which is the second parameter.
To use the above function, we simply need to do this:
needCallback(20, function(result){
console.log(result)
})
We can see clearly, that the first parameter is the number used for the computation, and the second parameter is the callback function. Pretty neat right?
Callbacks are very important, especially for processes that are dependent on the results of other computations in their flow of execution, say maybe a network call.
But what if I have a function that depends on another function, which depends on a third function to work? Fret not, JS got you handled.
Enter: Callback Chaining.
Callbacks can be chained so that functions are executed in a chronological order. To achieve this, one could nest callbacks inside other callbacks. take the example below:
//call functions in order
first('hello', function(){
second('my',function(){
third('friend',endFunction)
})
})
//Define the functions used below:
// the first function to be executed
function first(data,cb){
console.log(data);
cb();
}
//second function to be executed
function second(data,cb){
console.log(data);
cb();
}
//third function to be executed
function third(data, cb){
console.log(data);
cb();
}
//Last function to be executed
function endFunction(){
console.log('ended')
}
Pretty confusing, I know, but what has happened here is that the endFunction()
was chained to the third()
which was chained to the second()
which was eventually chained to the first()
. This ensures that the functions are executed in the order which they have been written.
Thankfully there are not too many cases where you’d need to do this, but if you absolutely have to, there is another concept called Promises which simplifies the whole chaining process.
Now that you understand callbacks, (hopefully) let's write out the example I gave previously as a JavaScript program.
function repairCar(callback = function(){}){
//do the car repairs
callback();
}
function callMe()
{
//do the function that calls me
}
//car breaks down, so You call John
repairCar(function(){
callMe
})
//John repairs the car and then calls me.
This is in no way an exhaustive tutorial on callbacks, but I hope it is enough to get you started.
Top comments (2)
Promises are preferred to avoid callback hell and much simpler is async await operations
Thank you, sairam459.
I did mention Promises as being an easier way, but didn't mention the async await operations.