If you’re fairly inexperienced with JavaScript but you’ve used jQuery, then its likely you’ve used callback functions. But maybe you don’t fully understand how they work or how they’re implemented.
In this post, which is based on what I’ve learned about callback functions in JavaScript, I’ll try to enlighten you on this fairly common technique. If you have anything to add, feel free to post a comment.
What is a Callback Function?The above-linked Wikipedia article defines it nicely:
A reference to executable code, or a piece of executable code, that is passed as an argument to other code.
Here’s a simple example that’s probably quite familiar to everyone, taken from jQuery:
$('#element').fadeIn('slow', function() { // callback function });
This is a call to jQuery’s fadeIn() method. This method accepts two arguments: The speed of the fade-in and an optional callback function. In that function you can put whatever you want.
When the fadeIn()
method is completed, then the callback function (if present) will be executed. So, depending on the speed chosen, there could be a noticeable delay before the callback function code is executed. You can read more about jQuery’s callback functions here.
If you’re writing your own functions or methods, then you might come across a need for a callback function. Here’s a very simple example of a custom callback function:
function mySandwich(param1, param2, callback) { console.log('Started eating my sandwich. It has: ' + param1 + ', ' + param2); callback(); } mySandwich('ham', 'cheese', function() { console.log('Finished eating my sandwich.'); });
Here we have a function called mySandwich
and it accepts three parameters. The third parameter is the callback function. When the function executes, it spits out an alert message with the passed values displayed. Then it executes the callback function.
Notice that the actual parameter is just “callback” (without parentheses), but then when the callback is executed, it’s done using parentheses. You can call this parameter whatever you want, I just used “callback” so it’s obvious what’s going on.
The callback function itself is defined in the third argument passed to the function call. That code has another alert message to tell you that the callback code has now executed. You can see in this simple example that an argument passed into a function can be a function itself, and this is what makes callbacks possible in JavaScript.
Here’s a CodePen that uses the simple example above:
Make Callback Functions in JavaScript OptionalOne thing you’ll notice about jQuery callbacks is that they’re optional. This means if a method accepts a callback, it won’t return an error if a callback is not included. In our simple example, the page will return an error if we call the function without a callback, like this:
function mySandwich(param1, param2, callback) { console.log('Started eating my sandwich. It has: ' + param1 + ', ' + param2); callback(); } // Missing required argument. Check the browser's developer tools for the error message: Uncaught TypeError: callback is not a function at mySandwich mySandwich('ham', 'cheese');
If you look at the console, you’ll see an error that says “Uncaught TypeError: callback is not a function” (or something similar) that appears after the initial console message.
To make the callback optional, we can just do this:
function mySandwich(param1, param2, callback) { console.log('Started eating my sandwich. It has: ' + param1 + ', ' + param2); if (callback) { callback(); } } // No third argument, but no error because we check for the callback first. mySandwich('ham', 'cheese');
Now, since we’re checking to ensure the existence of callback
, the function call won’t cause an error without it.
Finally, you can ensure that whatever value is passed as the third argument is in fact a proper function, by doing this:
function mySandwich(param1, param2, callback) { console.log('Started eating my sandwich. It has: ' + param1 + ', ' + param2); if (callback && typeof(callback) === 'function') { callback(); } } // Third argument is not a function mySandwich('ham', 'cheese', 'vegetables');
Notice that the function now includes a test using the typeof
operator, to ensure that whatever is passed is actually a function. The function call has a third argument passed, but it’s not a function, it’s a string. So the test using typeof
ensures no error occurs.
The CodePen below has a non-function argument passed as the callback.
A Note About Timing When Using Callback Functions in JavaScriptAlthough it is true that a callback function will execute last if it is placed last in the function, this will not always appear to happen. For example, if the function included some kind of asynchronous execution (like an Ajax call or an animation), then the callback would execute after the asynchronous action begins, but possibly before it finishes.
Here’s an example that uses jQuery’s animate()
method:
function mySandwich(param1, param2, callback) { console.log('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2); $('#sandwich').animate({ opacity: 0 }, 5000, function() { console.log('Animation complete!'); }); if (callback && typeof(callback) === "function") { callback(); } } mySandwich('ham', 'cheese', function() { console.log('Finished eating my sandwich.'); });
Notice that although the callback appears later in source order than the animation, the callback will actually execute long before the animation completes. In this case, solving this problem is easy: You just put the callback execution inside the animate
method’s callback function (where it says “Animation complete”).
This doesn’t cover all the details regarding asynchronous functions, but it should serve as a basic warning that callback functions will only execute last as long as all the code in the function is synchronous.
ConclusionUnderstanding how callback functions in JavaScript work is a nice technique to add to your collection of JavaScript design patterns. I hope this summary of callbacks helps you to understand this concept better. If you have anything technical to add, feel free to post a comment below.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4