Callback functions is extremely important in Javascript. They ' re pretty much everywhere. Originally coming from a to traditional C/java background I had trouble with this (and the whole idea of asynchronous PR ogramming), but I ' m starting to get the hang of it. Strangely, I Haven ' t found any good introductions to callback functions online-i mainly found bits of documentation on T He call () and apply () functions, or brief code snippits demonstrating their use-so, after learning the hard I decide D-to-try-to-write a simple introduction to callbacks myself.
Functions is objects
To understand callback functions your first has to understand regular functions. This might seen like a "duh" thing to say, but functions in Javascript is a bit odd.
Functions in Javascript is actually objects. Specifically, they ' re Function
objects created with the Function
constructor. A Function
object contains a string which contains the Javascript code of the function. If you're coming from a language like C or Java, might seem strange (how can code is a string?!) but it ' s actually run -of-the-mill for Javascript. The distinction between code and data is sometimes blurred.
1 |
// you can create a function by passing the |
2 |
// Function constructor a string of code |
3 |
var func_multiply = new Function( "arg1" , "arg2" , "return arg1 * arg2;" ); |
4 |
func_multiply(5,10); // => 50 |
One benefit of this function-as-object concept is so you can pass code to another function in the same-a-do you would pas s a regular variable or object (because the code is literally just an object).
Passing a function as a callback
Passing a function as an argument are easy.
01 |
// define our function with the callback argument |
02 |
function some_function(arg1, arg2, callback) { |
03 |
// this generates a random number between |
05 |
var my_number = Math.ceil(Math.random() * |
06 |
(arg1 - arg2) + arg2); |
07 |
// then we‘re done, so we‘ll call the callback and |
12 |
some_function(5, 15, function (num) { |
13 |
// this anonymous function will run when the |
15 |
console.log( "callback called! " + num); |
It might seem silly to go through all this trouble when the value could just is returned normally, but there is situation s where that ' s impractical and callbacks is necessary.
Don ' t block the
Traditionally functions work by taking input in the form of arguments and returning a value using a return statement Lly a single return statement at the end of the Function:one, entry point, and one exit point). This makes sense. Functions is essentially mappings between input and output.
Javascript gives us an option to do things a bit differently. Rather than wait around for a function to finish by returning a value, we can use the callbacks to do it asynchronously. This was useful for things a while to finish, like making an AJAX request, because we aren ' t holding up the brows Er. We can keep on doing other things while waiting for the callback to be called. In fact, very often we is required (or, rather, strongly encouraged) to doing things asynchronously in Javascript.
Here's a more comprehensive example this uses AJAX to load an XML file, and uses the call () function to call a callback Fu Nction in the context of the requested object (meaning if we call the this
keyword inside the callback function it Would refer to the requested object):
01 |
function some_function2(url, callback) { |
02 |
var httpRequest; // create our XMLHttpRequest object |
03 |
if (window.XMLHttpRequest) { |
04 |
httpRequest = new XMLHttpRequest(); |
05 |
} else if (window.ActiveXObject) { |
06 |
// Internet Explorer is stupid |
08 |
ActiveXObject( "Microsoft.XMLHTTP" ); |
11 |
httpRequest.onreadystatechange = function () { |
12 |
// inline function to check the status |
14 |
// this is called on every state change |
15 |
if (httpRequest.readyState === 4 && |
16 |
httpRequest.status === 200) { |
17 |
callback.call(httpRequest.responseXML); |
18 |
// call the callback function |
21 |
httpRequest.open( ‘GET‘ , url); |
25 |
some_function2( "text.xml" , function () { |
28 |
console.log( "this will run before the above callback" ); |
In this example we create the httpRequest
object with the load an XML file. The typical paradigm of returning a value at the bottom of the function No. longer works here. Our request is handled asynchronously, meaning. We start the request and tell it to call our function when it finishes .
The
We ' re using the anonymous functions here. It's important to remember that we could just as easily is using named functions, but for sake of brevity they ' re just WRI Tten Inline. The first anonymous function is run every time there's a state change in our HttpRequest
object. We ignore it until the state is 4 (meaning it's done) and the status is a (meaning it was successful). In the "real world" want to check if the request failed, but we ' re assuming the file exists and can is loaded by the B Rowser. This anonymous function was assigned to Httprequest.onreadystatechange
, so it was not run right away but rather Called every time there ' s a state change in our request.
When we finally finish our AJAX request, we do not have only run of the callback function but we use THE  call ()
& Nbsp;function. This is a different the calling a callback function. The method we used before of just running the function would work fine here, but I thought it would be worth demonstrating The use of the call ()
function. Alternatively you could use the apply ()
function (the difference between the. Beyond the scope of T His tutorial, but it involves how do you pass arguments to the function).
The neat thing about using is, the context in which, the call()
function is executed. This means if we use the this
keyword inside our callback function it refers to whatever we passed as the first AR Gument for call()
. In the If we refer to this inside our anonymous callback function we is referring to the from the responseXML
AJAX req Uest.
Finally, the second Console.log statement would run before the first, because the callback ' t executed until the request Is over, and until this happens the rest of the code goes right on ahead and keeps running.
Wrapping it Up
Hopefully now-should understand callbacks well enough-use them in your own code. I still find it hard-structure code that's based around callbacks (it ends up looking like spaghetti ... my mind is too a Ccustomed to regular structured programming), but they ' re a very powerful tool and one of the most interesting parts of th e Javascript language.
http://recurial.com/programming/understanding-callback-functions-in-javascript/