Categories
JavaScript Tutorials

Callback Functions

Because a function is just like any other data assigned to a variable, it can be defined, deleted, copied, and why not also passed as an argument to other functions?

Here’s an example of a function that accepts two functions as parameters, executes them, and returns the sum of what each of them returns.

function invoke_and_add(a, b){
  return a() + b();
}

Now let’s define two simple additional functions that only return hardcoded values:

function one() {
  return 1;
}
function two() {
  return 2;
}

Now we can pass those functions to the original function add() and get the result:

invoke_and_add(one, two);
3

Another example of passing a function as a parameter is to use anonymous functions. Instead of defining one() and two(), you can simply do:

invoke_and_add(function(){return 1;}, function(){return 2;})

When you pass a function A to another function B and B executes A, it’s often said that A is a callback function. If A doesn’t have a name, then you can say that it’s an anonymous callback function.

When are the callback functions useful? Let’s see some examples that demonstrate the benefits of the callback functions, namely:

  • They let you pass functions without the need to name them (which means there are less global variables). 
  • You can delegate the responsibility of calling a function to another function (which means there is less code to write). 
  • They can help with performance

Callback Examples

Take a look at this common scenario: you have a function that returns a value, which you then pass to another function. In our example, the first function, multiplyByTwo(), accepts three parameters, loops through them, multiplying them by two and returns an array containing the result. The second function, addOne(), takes a value, adds one to it and returns it.

function multiplyByTwo(a, b, c) {
  var i, ar = [];
  for(i = 0; i < 3; i++) {
    ar[i] = arguments[i] * 2;
  }
  return ar;
}
function addOne(a) {
  return a + 1;
}

Testing the functions we have so far:

multiplyByTwo(1, 2, 3);
//[2, 4, 6]
addOne(100)
//101

Now let’s say we want to have an array myarr that contains three elements, and each of the elements is to be passed through both functions. First, let’s start with a call to multiplyByTwo().

var myarr = [];
myarr = multiplyByTwo(10, 20, 30);
//[20, 40, 60]

Now loop through each element, passing it to addOne().

for (var i = 0; i < 3; i++) {myarr[i] = addOne(myarr[i]);}
myarr;
//[21, 41, 61]

As you see everything works fine, but there’s still room for improvement. One thing is that there were two loops. Loops can be expensive if they go through a lot or repetitions. We can achieve the result we want with one loop only. Here’s how to modify multiplyByTwo() so that it accepts a callback function and invokes callback on every iteration:

function multiplyByTwo(a, b, c, callback) {
  var i, ar = [];
  for(i = 0; i < 3; i++) {
    ar[i] = callback(arguments[i] * 2);
  }
  return ar;
}

By using the modified function, the whole work is now done with just one function call, which passes the start values and the callback.

myarr = multiplyByTwo(1, 2, 3, addOne);
//[3, 5, 7]

Instead of defining addOne() we can use an anonymous function, this way saving an extra global variable.

myarr = multiplyByTwo(1, 2, 3, function(a){return a + 1});
//[3, 5, 7]

Anonymous functions are easy to change should the need arise:

myarr = multiplyByTwo(1, 2, 3, function(a){return a + 2});
//[4, 6, 8]

Examples

Create a function to add given two numbers and then multiply 10 to the sum using a call back function.

We need to create two functions. One function to find the sum of the two numbers and one callback function to multiply the sum by 10.

function solve(a,b,callback) {
  var sum = a + b;
  callback(sum);
}

function multiply(num) {
  num * 10;
}

solve(2,3,multiply);

Create a function to find the sum of given three numbers and then find the average using a callback function.

function solve(a,b,c,avg) {
  var sum = a + b + c;
  avg(sum);
}

function average(total) {
  total/3;
}

solve(1,2,3,average);

Create a function to find the prime numbers between given two numbers and then print them in the console using a callback function.

function findPrime(a,b,callback){
  for(var i=a;i<=b;i++) {
    var count = 0;
    for(var j=1;j<=i;j++) {
      if(i%j===0) {
        count++;
      }
    }
    if(count===2) {
      callback(i);
    }
  }    
}

function print(num){
  console.log(num)
}

findPrime(10,20,print);