How to explain callbacks in plain english? How are they different from calling one function from another function?

I am going to try to keep this dead simple. A "callback" is any function that is called by another function which takes the first function as a parameter. A lot of the time, a "callback" is a function that is called when something happens. That something can be called an "event" in programmer-speak.

Imagine this scenario: you are expecting a package in a couple of days. The package is a gift for your neighbor. Therefore, once you get the package, you want it brought over to the neighbors. You are out of town, and so you leave instructions for your spouse.

You could tell them to get the package and bring it to the neighbors. If your spouse was as stupid as a computer, they would sit at the door and wait for the package until it came (NOT DOING ANYTHING ELSE) and then once it came they would bring it over to the neighbors. But there's a better way. Tell your spouse that ONCE they receive the package, they should bring it over the neighbors. Then, they can go about life normally UNTIL they receive the package.

In our example, the receiving of the package is the "event" and the bringing it to the neighbors is the "callback". Your spouse "runs" your instructions to bring the package over only when the package arrives. Much better!

This kind of thinking is obvious in daily life, but computers don't have the same kind of common sense. Consider how programmers normally write to a file:

fileObject = open(file)
# now that we have WAITED for the file to open, we can write to it
fileObject.write("We are writing to the file.")
# now we can continue doing the other, totally unrelated things our program does

Here, we WAIT for the file to open, before we write to it. This "blocks" the flow of execution, and our program cannot do any of the other things it might need to do! What if we could do this instead:

# we pass writeToFile (A CALLBACK FUNCTION!) to the open function
fileObject = open(file, writeToFile)
# execution continues flowing -- we don't wait for the file to be opened
# ONCE the file is opened we write to it, but while we wait WE CAN DO OTHER THINGS!

It turns out we do this with some languages and frameworks. It's pretty cool! Check out Node.js to get some real practice with this kind of thinking.


Often an application needs to execute different functions based upon its context/state. For this, we use a variable where we would store the information about the function to be called. ‪According to its need the application will set this variable with the information about function to be called and will call the function using the same variable.

In javascript, the example is below. Here we use method argument as a variable where we store information about function.

function processArray(arr, callback) {
    var resultArr = new Array(); 
    for (var i = arr.length-1; i >= 0; i--)
        resultArr[i] = callback(arr[i]);
    return resultArr;
}

var arr = [1, 2, 3, 4];
var arrReturned = processArray(arr, function(arg) {return arg * -1;});
// arrReturned would be [-1, -2, -3, -4]

How to explain callbacks in plain English?

In plain English, a callback function is like a Worker who "calls back" to his Manager when he has completed a Task.

How are they different from calling one function from another function taking some context from the calling function?

It is true that you are calling a function from another function, but the key is that the callback is treated like an Object, so you can change which Function to call based on the state of the system (like the Strategy Design Pattern).

How can their power be explained to a novice programmer?

The power of callbacks can easily be seen in AJAX-style websites which need to pull data from a server. Downloading the new data may take some time. Without callbacks, your entire User Interface would "freeze up" while downloading the new data, or you would need to refresh the entire page rather than just part of it. With a callback, you can insert a "now loading" image and replace it with the new data once it is loaded.

Some code without a callback:

function grabAndFreeze() {
    showNowLoading(true);
    var jsondata = getData('http://yourserver.com/data/messages.json');
    /* User Interface 'freezes' while getting data */
    processData(jsondata);
    showNowLoading(false);
    do_other_stuff(); // not called until data fully downloaded
}

function processData(jsondata) { // do something with the data
   var count = jsondata.results ? jsondata.results.length : 0;
   $('#counter_messages').text(['Fetched', count, 'new items'].join(' '));
   $('#results_messages').html(jsondata.results || '(no new messages)');
}

With Callback:

Here is an example with a callback, using jQuery's getJSON:

function processDataCB(jsondata) { // callback: update UI with results
   showNowLoading(false);
   var count = jsondata.results ? jsondata.results.length : 0;
   $('#counter_messages').text(['Fetched', count, 'new items'].join(' '));
   $('#results_messages').html(jsondata.results || '(no new messages)');
}

function grabAndGo() { // and don't freeze
    showNowLoading(true);
    $('#results_messages').html(now_loading_image);
    $.getJSON("http://yourserver.com/data/messages.json", processDataCB);
    /* Call processDataCB when data is downloaded, no frozen User Interface! */
    do_other_stuff(); // called immediately
}

With Closure:

Often the callback needs to access state from the calling function using a closure, which is like the Worker needing to get information from the Manager before he can complete his Task. To create the closure, you can inline the function so it sees the data in the calling context:

/* Grab messages, chat users, etc by changing dtable. Run callback cb when done.*/
function grab(dtable, cb) { 
    if (null == dtable) { dtable = "messages"; }
    var uiElem = "_" + dtable;
    showNowLoading(true, dtable);
    $('#results' + uiElem).html(now_loading_image);
    $.getJSON("http://yourserver.com/user/"+dtable+".json", cb || function (jsondata) {
       // Using a closure: can "see" dtable argument and uiElem variables above.
       var count = jsondata.results ? jsondata.results.length : 0, 
           counterMsg = ['Fetched', count, 'new', dtable].join(' '),
           // no new chatters/messages/etc
           defaultResultsMsg = ['(no new ', dtable, ')'].join(''); 
       showNowLoading(false, dtable);
       $('#counter' + uiElem).text(counterMsg);
       $('#results'+ uiElem).html(jsondata.results || defaultResultsMsg);
    });
    /* User Interface calls cb when data is downloaded */

    do_other_stuff(); // called immediately
}

Usage:

// update results_chatters when chatters.json data is downloaded:
grab("chatters"); 
// update results_messages when messages.json data is downloaded
grab("messages"); 
// call myCallback(jsondata) when "history.json" data is loaded:
grab("history", myCallback); 

Closure

Finally, here is a definition of closure from Douglas Crockford:

Functions can be defined inside of other functions. The inner function has access to the vars and parameters of the outer function. If a reference to an inner function survives (for example, as a callback function), the outer function's vars also survive.

See also:

  • http://javascript.crockford.com/survey.html
  • http://api.jquery.com/jQuery.when/
  • http://api.jquery.com/jQuery.getJSON/
  • http://github.com/josher19/jQuery-Parse