JavaScript Callbacks

JavaScript Callbacks

Summary

In this tutorial, you will learn about synchronous and asynchronous callbacks in JavaScript. Any function passed as an argument to any other function is called callback function. This means that a function can call to any other function and it can run after first function has finished.

We can passed a function to any other function as an argument because in JavaScript functions are first-class citizens, so we can store the function into a variable and pass it any other function as an argument or return them from other function as value.

Storing functions

Define a function sub() and assign the function name to the variable x:

function sub(a, b) {
    return a - b
}

let x = sub

Here we are not executing the function but reference the function. You can also note that we didn't include the parenthesis at the time of assigning. By doing this we can execute this in two ways. First we can call it as normal as follow:

let result = sub(20,10)

Alternatively we can call the sub() function by x variable as follow:

let result = x(20,10)

You see that we have defined a function and store it into a variable and call it by two ways. This shows that how functions are first class citizens in the JavaScript.

Sequence

The other main thing in the JavaScript is sequence. It means functions are executed in the sequence they are called and not in the sequence they are defined. Below example show that how they are executed in sequence?

function lastName() {
  console.log("Hussain")
}

function firstName() {
  console.log("Fiyaz")
}

firstName()
lastName()

The result will be like this:

Fiyaz
Hussain

Yo see that we define lastName() function first and then the firstName() but they executed by sequence of their call so we get Fiyaz firstly and then Hussain in the console.

Sequence Control

Now as we now that in JavaScript sequence matters, sometimes we want to have the better control at sequence.

For example we want calculate the percentage of the student and then display the result.

To do this we will call a function to calculate the percentage, save the result and then a new function to display the result.

//calculate percentage
function calculator(marks) {
  let per = 0
  let total = 150
  per = (marks/total) * 100
  return per
}
// save the result
let result = calculator(125)

function displayer(r){
  console.log(r)
}

//display the result
displayer(result)

The other way is to let the calculator function call the displayer function to calculate and display the result as follow:

//calculate percentage
function calculator(marks) {
  let per = 0
  let total = 150
  per = (marks/total) * 100
//display the result
  displayer(per)
}

function displayer(r){
  console.log(r)
}

If you notice in both functions that you have some issues with both methods. For first method you have to call two functions to show the result.

And in the second method the calculator function will display the result and we can not stop it.

There come callbacks to rescue you in these situations.

Callbacks

Callbacks allow us to run the calculator function with a callback function, so the calculator function will call the callback function after it has finished the calculation.

//calculate percentage
function calculator(marks, callBackFunc) {
  let per = 0
  let total = 150
  per = (marks/total) * 100
callBack(per)
}

function displayer(r){
  console.log(r)
}

calculator(100, displayer)

You can see that a function named as displayer is passed to another function calculator as callback and the calculator function will call this function after completing the calculations.

One more thing to take care is that when you pass a function as an argument, pass it without parenthesis.

When to use

The above examples are really simple because there are only to show you the syntax of the callback system and these examples are not really exciting. The purpose of these examples is to show you the syntax of callback functions.

You will find these callbacks more exciting and will learn deep logic when we you will use in asynchronous functions. In asynchronous functions, one function has to wait for the other function to complete(e.g. waiting for data to upload).

Asynchronous

A good example is JavaScript setTimeout()

Mostly callbacks are used with asynchronous functions. It is executed after the execution of the high-order function that uses the callback. Let's take a look into the following example:

setTimeout(() => {
  console.log("Waited for 1 second.");
}, "1000")

here we have passed a callback function which is printing the log but it will wait for one second to be executed. After one second it will print the log. Instead of passing the whole function we can pass a callback function as follow:

setTimeout(callBackFunc, "1000")

const callBackFunc = () => {
  console.log("Waited for 1 second.");
}

Remember, never include parenthesis while passing the function as parameter to any other function.

Now if you have to upload some external file or resource, then you can not perform any action on it before it is completely uploaded. Here callback function comes handy to the developers.

Let's take a look at the following code:

function myRunner (param) {
  console.log(param)
}

function uploadData = () {
  let request = new XMLHttpRequest()
  request.open('GET',  'file.html')
  request.onload = function() {
    if(request.status === upload) {
      callBackFunc('some success message or info')
    } else {
      callBackFunc("Error: " + req.status)
    }
  }
  request.send()
}

uploadData(myRunner)

Here myRunner is used as a callback. myRunner is passed to uploadData as an argument.

Conclusion

Callback functions are passed to another function as an argument. Only higher order function can accept the other function as an argument. Callback functions can be synchronous or asynchronous. In real world we mostly use callback functions in asynchronous.

Did you find this article valuable?

Support Fiyaz Hussain by becoming a sponsor. Any amount is appreciated!