Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Usefulness of callback functions

In Javascript there is a possibility to define a function X and pass it as an argument to another function Y.

Such a function X is called a callback function.

Could you explain why is useful to use callback functions in some clear examples (e.g. send some fiddle links with demonstration)? I can see one usefulness, it's code readability, but I'm not sure in this, because code with callbacks looks more complex.

The only usefulness is it's use in browser environment and asynchronous execution in AJAX? What about another Javascript implementations (e.g. Rhino)? Are callbacks useful there as well? Or does their usefulness depend only on the environment where Javascript is executed?

thank you

like image 226
xralf Avatar asked Sep 08 '11 11:09

xralf


People also ask

Are callback functions good?

The functions that receive the callback function as a parameter are the ones responsible to call back the callback function. Callbacks are great because they open up a lot of programming possibilities.

What is the advantage of callback function in C?

The main advantage of using callbacks is that you can call a subroutine defined in higher software level from a lower software level subroutine.

Where do we use callbacks?

Callbacks are a great way to handle something after something else has been completed. By something here we mean a function execution. If we want to execute a function right after the return of some other function, then callbacks can be used. JavaScript functions have the type of Objects.

What is the use of callback function in JavaScript?

A callback is a function passed as an argument to another function.


1 Answers

Callbacks as parameters

Callbacks are useful because they allow you to "configure" a function with code.

The archetypal example for this is a sorting function which allows you to specify your own sort criteria. I 'm going to use a function that returns the minimum value of an array based on some criteria because it's simpler than a sort, but it still will serve fine as an illustration:

function min(collection, property) {
    if (collection.length == 0) {
        return null;
    }

    var minIndex = 0;
    var minValue = collection[0][property];
    for (var i = 1; i < collection.length; ++i) {
        if (minValue > collection[i][property]) {
            minValue = collection[i][property];
            minIndex = i;
        }
    }

    return collection[minIndex];
}

var items = [
    { name: "John", age: 20 }, { name: "Mary", age: 18 }
    ];

alert(min(items, 'age').name); // prints "Mary"

See this code run. What is the problem with it?

The problem is that while we made some effort in order to create a configurable min function (it finds the minimum based on any property we specify), it's still pretty limited in the general sense because it can only find the minimum based on one single property.

What if our data was like this?

var items = [ "John/20", "Mary/18" ];

This is no longer an array of objects, but an array of formatted strings. It has the same data as the original collections, but in a different structure. As a result, the original min function cannot be used to process it.

Now we could write another version of min that works with strings instead of objects, but that would be kind of pointless (there are infinitely many ways to represent the same data). This might be OK as a quick and dirty solution for one particular case, but consider the problem of a library writer: how could they write one function useful to everyone, without knowing how the data will be structured in each case?

Callbacks to the rescue

Simple: make the min function more powerful by allowing its user to specify how to extract the criteria from the data. This sounds very much like "giving the function code to extract the criteria from the data", which is what we are going to do. min will accept a callback:

function min(collection, callback) {
    if (collection.length == 0) {
        return null;
    }

    var minIndex = 0;
    var minValue = callback(collection[0]);
    for (var i = 1; i < collection.length; ++i) {
        if (minValue > callback(collection[i])) {
            minValue = callback(collection[i]);
            minIndex = i;
        }
    }

    return collection[minIndex];
}

var items = [ "John/20", "Mary/18" ];

var minItem = min(items, function(item) {
    return item.split('/')[1]; // get the "age" part
});

alert(minItem);

See this code run.

Now at last our code is reusable. We can easily configure it to work both with the first and the second type of data with minimal effort.

See the callback-enabled function handle both types of data. This is the result of the extreme flexibility we gained as a result of allowing the user to provide code to run as part of our function, in the form of a callback.

Callbacks in asynchronous programming

Another major use of callbacks is to enable asynchronous programming models. This is useful in all cases where you schedule an operation to complete, but do not want your program to stop running until the operation has completed.

In order for this to work, you provide the operation with a callback function and effectively tell it: go do this work for me, and when you are done, call me back. You are then free to go ahead and do anything you like, knowing that when the results are available the function you specified will run.

This is most visible in the web with AJAX: you fire off a request to a web server, and when the response has been received you act upon it in some manner. You don't want to wait on the spot for the response because it might take a lot of time (e.g. if there are connection problems) and you don't want your program to be unresponsive for all that time.

For an example of an AJAX callback, see the documentation for the jQuery load function.

like image 70
Jon Avatar answered Oct 06 '22 01:10

Jon