Home Functions JavaScript Callback Functions – The Absolute Basics
formats

JavaScript Callback Functions – The Absolute Basics

in Functions.

Callbacks are a critical tool for properly handling asynchronous events in JavaScript.

Timing is one of the most difficult techniques to master in JavaScript. At first, many look to the setTimeout() method to address the asynchronous nature of JavaScript. But that is most often not the best approach. The concept of a callback function is one of the things that makes JavaScript such a special language.

In order to understand callbacks, it is important to be aware that functions are first class citizens in JavaScript. This means (among other things) that a function can be passed as a value to another function. The upside to this is the fact that if you call function A, and pass it function B as an argument, then inside of function A, you can execute function B. That’s really what it all boils down to: You call a function, and pass it another function, and inside of the first function, when an event that you need to complete has completed, then you “call back” to the function that was passed in.

While you can pass a named function as an argument, quite often you will see an anonymous function passed. Before we demonstrate a callback function, let’s demonstrate why they are so helpful in JavaScript.

Example # 1

PHP FIle:

<?php
	sleep(3);
	header('content-type: text/javascript; charset=utf-8');
?>

console.log("1) hello from the script you just loaded");

Client-side JavaScript:

function getScript(){
//create a script element and inject it into the page
var script = document.createElement('script');
script.src = 'http://sub1.kevinchisholm.com/blog/examples/sleep1.php';
document.getElementsByTagName('head')[0].appendChild(script);
};

getScript();
console.log("2) the new script has been loaded"); //fires before the script finishes loading

In example # 1, we have two chunks of code: A server-side page that sleeps for three seconds, and then returns a JavaScript file. That JavaScript file simply outputs a message to the console.

When the script loads, it outputs a message to the console (message # 1). We want that message to be output before the 2nd message. The problem is that the script loading process is asynchronous; it could take 200ms, it could take five minutes. I’ve forced the PHP page that returns the JavaScript to “sleep” for three seconds, to exaggerate the effect. But the bottom line is: we don’t know how long that script loading process will take, which means that we have to find a way to execute message # 2 only after the script has finished loading.

Here is a JSFiddle link for Example # 1: http://jsfiddle.net/CZeLv/

Example # 2

function getScript(callback){
   //create a script element and inject it into the page
   var script = document.createElement('script');
   script.src = 'http://sub1.kevinchisholm.com/blog/examples/sleep1.php';
   document.getElementsByTagName('head')[0].appendChild(script);

   //when the new script's load event fires, execute the callback
   script.onload = callback;
};

getScript(function(){
   console.log("the new script has been loaded"); //much better!
});

In Example # 2, we pass an anonymous function to the getScript() method. Inside of getScript(), we take advantage of the fact that any dynamically loaded script element has an “onload” event. We assign that event to the callback that was passed-in. This means that when the script has successfully loaded, we execute the callback. As a result, we have complete control over the timing of events, even though the entire process is asynchronous. What happens is that message # 1 first first, and them message # 2. This is what we want.

Here is a JSFiddle link for Example # 2: http://jsfiddle.net/dfCM2/

What if the script that we are loading has properties and methods that we need to act upon once the script is available? In example # 3, we demonstrate how using a callback allows us to call a method that does not exist before the script is loaded, but we are able to control the timing of when it is called, so that it works every time.

Example # 3

PHP File:

<?php
sleep(3);
header('content-type: text/javascript; charset=utf-8');
?>

window.getSecretWord = function(){
	return "milkshake";
};

Client-side JavaScript:

function getScript(callback){
   //create a script element and inject it into the page
   var script = document.createElement('script');
   script.src = 'http://sub1.kevinchisholm.com/blog/examples/sleep2.php';
   document.getElementsByTagName('head')[0].appendChild(script);

  //when the new script's load event fires, execute the callback
   script.onload = callback;
};

getScript(function(){
   //window.getSecretWord now exists
   var secret = getSecretWord();

   //output the secret
   console.log("The secret word is: " + secret);
});

In example # 3, after the PHP file “sleeps” for three seconds, it adds a new method to the window object. That method returns a secret word. We need access to that secret word in our page, but we need to make sure that we don’t try to call the method getSecretWord() until it is available. By passing a callback to the getScript() function, we yield control to getScript() and basically ask it to fire our callback for us. Inside of getScript(), the script’s onload event is assigned to the callback, which means we only attempt to execute getSecretWord() once we know for sure that it exists (because the script’s onload event fired).

The important thing to keep in mind here is that if the script we are loading takes 5 minutes to return, or never returns, it does not matter. Our callback will only fire when that script successfully loads. While it is loading, the user still has complete access to the browser. That is really important.

Here is a JSFiddle link for Example # 3: http://jsfiddle.net/fAn4g/

Summary

In this article, we covered the very basics of JavaScript callback functions. We learned that functions are first-class citizens in JavaScript, and can be passed around to and from functions. We looked at an example of why callbacks are so critical to the JavaScript language and how they are an excellent tool for working around the asynchronous nature of the language,

Helpful Links for JavaScript Callback Functions

http://recurial.com/programming/understanding-callback-functions-in-javascript/

http://www.impressivewebs.com/callback-functions-javascript/

http://javascript.about.com/od/byexample/a/usingfunctions-callbackfunction-example.htm

show
 
close