Javascript Callbacks — How do they work ?
By: Tejaswi Kasat
Tags: Javascript Callback, JavaScript, Js, Callback

If you code, it is certain that you use methods and functions no matter what programming language you are using. In javascript, since a lot of things works asyncronously, 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 which 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 console.

[thejsway@jsmachine]$ node callback.js

10

Now, let’s do some changes to this function and make it asyncronous 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 - first is a function to execute and the second is the time in milliseconds. We have added an anonymous arrow function which returns 10 and a timeout of 3000 milliseconds which is equivalent to 3 seconds. And later on, we have 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 asyncronous function which will return the number only after 3 seconds are passed.

[thejsway@jsmachine]$ node callback.js

undefined

So there is a problem. How to access this data returned? How to run the code after this asyncronous function is completed? The answer is callbacks.

As the name suggests, callback is simply a function which is executed after another function is completed. In our case, a function which 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 in getNumber() function i.e. cb. When we call getNumber() in the above format, a function is passed and is assigned to cb 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 console will be called.

The output will be now as follows. The output is printed after 3 seconds are completed.

[thejsway@jsmachine]$ node callback.js

10

That’s simply a callback function 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 asyncronous by using setTimeout() function and check if the number passed is even or not after two seconds. If the number is even, pass true in callback and if the number is odd, pass false. If no number is passed, pass error message in callback. We will write a callback function which will take two arguments, first is isEven and second is 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 return here before callback function in order to stop the further execution of if cases since an error occurred.

Now as our isEven() function is ready, lets call this function with different use cases and analyse 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:

[thejsway@jsmachine]$ node callback.js

10: true

11: false

undefined: No number is passed

That’s simply how a callback works.

If you wan’t 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 follow: https://thejsway.medium.com/