Javascript Callbacks — How do they work ?
If you code, you certainly use methods and functions no matter what programming language you are using. In javascript, since a lot of things work asynchronously, callbacks add a great feature to perform the post tasks. Let’s dive deep into it and understand what are they and how they work.
Let’s write a simple javascript function that returns a number
const getNumber = () => {
return 10
}
console.log(getNumber())
This code is self-explanatory. A function getNumber()
when called returns a number 10 and logs it in the console.
$ node callback.js
10
Now, let’s do some changes to this function and make it asynchronous by adding a setTimeout()
function.
const getNumber = () => {
setTimeout(() => {
return 10
},3000)}
console.log(getNumber())
In the above code, we have added a setTimeout()
function which expects 2 parameters - the first is a function to execute and the second is the time in milliseconds. We have added an anonymous arrow function that returns 10 and a timeout of 3000 milliseconds which is equivalent to 3 seconds. And later on, we logged the output of getNumber()
in console.log()
. But, what will be logged here after running this code? The answer is undefined and the reason is setTimeout()
is an asynchronous function that will return the number only after 3 seconds are passed.
$ node callback.js
undefined
So there is a problem. How to access this data returned? How to run the code after this asynchronous function is completed? The answer is callbacks.
As the name suggests, the callback is simply a function that is executed after another function is completed. In our case, a function that will be called after setTimeout()
function is completed after 3 seconds. So let’s do that.
const getNumber = (cb) => {
setTimeout(() => {
cb(10)
},3000)
}
// Passed a function in getNumber() function as a parameter
getNumber((output) => {
console.log(output)
})
In the above code, we have made some changes.
We have removed
console.log()
when calling getNumber().We added a new parameter while calling
getNumber()
function and also added a parameter ingetNumber()
function i.e. cb.When we call
getNumber()
in the above format, a function is passed and assigned tocb
parameter.After
setTimeout()
time i.e. 3 seconds, is over, it will run the function and inside that, it will call the cb function and passes an integer 10 as its parameters.Now the function where output is logged in the console will be called.
The output will be now as follows. The output is printed after 3 seconds are completed.
$ node callback.js
10
That’s simply a callback function that works. This is the simplest function written. We can write much more complex callback functions for different scenarios and perform different operations.
Let’s take one more example but this time let’s add some complexity to it.
We will write a function named
isEven()
which takes in an integer and a callback function as an argument.We will make this function asynchronous by using the
setTimeout()
function and checking if the number passed is even or not after two seconds.If the number is even, pass true in the callback, and if the number is odd, pass false. If no number is passed, pass an error message in the callback.
We will write a callback function that will take two arguments, the first is
isEven
and the second is an error message.
So following is the function isEven()
const isEven = (number, cb) => {
setTimeout(() => {
if(!number) {
return cb(undefined, "No number is passed")
}
if(number % 2 === 0) {
cb(true, undefined)
} else {
cb(false, undefined)
}
}, 2000)
}
We have added a return here before the callback function to stop the further execution of if cases since an error occurred.
Now as our isEven()
function is ready, let's call this function with different use cases and analyze their output.
// Passed 10 to check if it is even or not
isEven(10, (result, error) => {
if(error){
console.log("10:" + error)
} else {
console.log("10: " + result)
}
})
// Passed 11 to check if it is even or not
isEven(11, (result, error) => {
if(error){
console.log("11: " + error)
}
else {
console.log("11: " + result)
}
})
// Passed undefined to check if it is even or not
isEven(undefined, (result, error) => {
if(error){
console.log("undefined: " + error)
}
else {
console.log("undefined: " + result)
}
})
In the first function, we have passed 10. Since it is even, the output must be true
.
In the second function, we have passed 11. Since it is odd, the output must be false
.
In the third function, we have passed undefined. Since no number is passed, the error message must be shown.
Putting it all together, we have:
const isEven = (number, cb) => {
setTimeout(() => {
if(!number) {
return cb(undefined, "No number is passed")
}
if(number % 2 === 0) {
cb(true, undefined)
} else {
cb(false, undefined)
}
}, 2000)
}
// Passed 10 to check if it is even or not
isEven(10, (result, error) => {
if(error){
console.log("10:" + error)
}
else {
console.log("10: " + result)
}
})
// Passed 11 to check if it is even or not
isEven(11, (result, error) => {
if(error){
console.log("11: " + error)
}
else {
console.log("11: " + result)
}
})
// Passed undefined to check if it is even or not
isEven(undefined, (result, error) => {
if(error){
console.log("undefined: " + error)
}
else {
console.log("undefined: " + result)
}
})
On running this code, we get:
$ node callback.js
10: true
11: false
undefined: No number is passed
That’s simply how a callback works.
If you want to read further, read about promises in the next article.
Thanks for reading this article, if you would like to read more articles on javascript, don’t forget to bookmark: blog.tdevs.in