Callback Function JavaScript

Callback Function JavaScript

In this tutorial, we would like to help you to explain JavaScript callback functions like what is callback function in javascript and how to use them.

JavaScript Callback Function

In JavaScript, the callback function is that. Which is called after some block of code is executed.

Suppose that you the following numbers array:

let numbers = [1, 2, 3, 5, 8, 9, 10, 12];

To find all the even numbers in the array, you can use the filter() method of the Array object.

The filter() method creates a new array with the elements that pass the test implemented by a function.

See the following example:

function evenNumber(number) {
    return number % 2 == 0;
}

Now, you can pass the evenNumber() to the filter() method:

const evenNum = numbers.filter(evenNumber);
console.log(evenNum); // [2, 8, 10, 12]

In this example, the evenNumber is a callback function. When you pass a callback function into another function, you just pass the reference of the function i.e., the function name without the parentheses ().

If you want to write less code for above example, you can use an anonymous function as a callback:

let numbers = [1, 2, 3, 5, 8, 9, 10, 12];
let evenNums = numbers.filter(function(number) {
    return number % 2 == 0;
});
console.log(evenNums); //[2, 8, 10, 12]

Callback as an Arrow Function

In ES6, you can use the arrow functions:

let evenNumbers = numbers.filter(number => number % 2 == 0);

If you work on web browsers, you often listen to an event e.g., a button click and take some actions if the event happens.

Suppose that you have a button with the id my-btn:

<button id="my-btn">Save</button>

To run some js code when the button is clicked, you use a callback and pass it to the addEventListener() method:

function btnClicked() { 
   // do something here
}
let btn = document.querySelector('#my-btn');
btn.addEventListener('click',btnClicked);

The btnClicked in this example is a callback. When the button is clicked, the btnClicked() function is called to carry some actions.

In javascript, Callbacks are used in two ways:

  • synchronous callback functions.
  • asynchronous callback functions.

Synchronous callback functions

If js scripts execute sequentially from top to bottom, it is synchronous. The evenNumber() function is an example of a synchronous callback function.

See the following example:

let numbers = [1, 2, 3, 5, 8, 9, 10, 12];
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 2, 3, 5, 8, 9, 10, 12]

Here, the sort() method completes first before the console.log() executes:

Asynchronous callback functions

In Asynchronous callback functions, Some actions that we initiate now, but they finish later.

Suppose that you need to develop a script that downloads a picture from a remote server and process it after the download completes:

function download(url) {
    // ...
}

function process(picture) {
    // ...
}

download(url);
process(picture);

However, downloading a picture from a remote server takes time depending on the network speed and the size of the picture.

The following code uses the setTimeout() function to simulate the download() function:

function download(url) {
    setTimeout(() => {
        // script to download the picture here
        console.log(`Downloading ${url} ...`);
    }, 3* 1000);
}

And this code emulates the process() function:

function process(picture) {
    console.log(`Processing ${picture}`);
}

When you execute the following code:

let url = 'https://www.example.com/foo.png';

download(url);
process(url);

you will get the following output:

Processing https://example.com/foo.png
Downloading https://example.com/foo.png

This is not what you expected because the process() function executes before the download() function. The correct sequence should be:

  • Download the picture, wait for it to complete.
  • Process the picture.

To fix the issue above, you can pass the process() function to the download() function and execute the process() function inside the download() function once the download completes, like this:

function download(url, callback) {
    setTimeout(() => {
        // script to download the picture here
        console.log(`Downloading ${url} ...`);
        
        // process the picture once it is completed
        callback(url);
    }, 3000);
}

function process(picture) {
    console.log(`Processing ${picture}`);
}

let url = 'https://wwww.example.com/pic.png';
download(url, process);

Output:

Downloading https://www.example.com/pic.png
Processing https://www.example.com/pic.png

Now, it works as expected.

In this example, the process() is a callback passed into an asynchronous function.

When you use callbacks to continue code execution after asynchronous operations, these callbacks are called asynchronous callbacks.

By using asynchronous callbacks, you can register an action in advance without blocking the entire operation.

To make the code cleaner, you can define the process() function as an anonymous function:

function download(url, callback) {
    setTimeout(() => {
        // script to download the picture here
        console.log(`Downloading ${url} ...`);
        // process the picture once it is completed
        callback(url);

    }, 3000);
}

let url = 'https://www.javascripttutorial.net/pic.jpg';
download(url, function(picture) {
    console.log(`Processing ${picture}`);
}); 

Handling errors

The download() function assumes that everything works fine and does not consider any exceptions. The following code introduces two callbacks: success and failure to handle the success and failure cases respectively:

function download(url, success, failure) {
    setTimeout(() => {
        // script to download the picture here
        console.log(`Downloading ${url} ...`);
        // over simplification
        let error = url.length === 0 || !url; 
        // call the failure or success callback
        error ? failure(url) :  success(url);
    }, 3000);
}

download('',
    function(picture) {
        console.log(`Processing the picture ${picture}`);
    },
    function(picture) {
        console.log(`Handling error...`);
    }
);

Conclusion

In this tutorial, you have learned everything about JavaScript callback functions and also learned synchronous callback functions, asynchronous callback functions in js.

Leave a Reply

Your email address will not be published. Required fields are marked *