Callback functions often seem quite confusing or complicated at first, but if we take a look under the hood we’ll find that they’re fairly straightforward. The chances are that you’ve already used them.
Callbacks are typically used to run a piece of code after a certain event has happened. Whether this event is mouse-clicking on a link, data being written to a database, or just another piece of code finishing executing isn’t important, as it could be just about anything. A callback function itself is typically an anonymous function—a function declared without a name—that’s passed directly into the receiving function as a parameter. Don’t worry if this just seems like jargon right now; we’ll look at code examples soon and you’ll see how easy it actually is!
Running a Callback Function
Simply declare a new function called setTimeout that accepts the parameters callback and delay; the names aren’t important—they can be anything you want. The following code snippet demonstrates this (note that you’ll not be able to run this in a JavaScript console):
The callback parameter is expected to be a function, which can be invoked at a specific
point in the setTimeout function 1. In this case you’re passing it a simple anonymous function 2 that will write a message to the console log. So when the setTimeout function deems it appropriate, it will invoke the callback and the message will be logged to the console. That’s not so difficult, is it?
If JavaScript is your first programming language you’ll have no idea how weird this concept of passing anonymous functions around looks to those coming in from different backgrounds. But the ability to operate like this is one of JavaScript’s great strengths. Typically you won’t generally look inside the functions running the callbacks,whether it’s setTimeout, jQuery’s ready, or Node’s createServer. The documentation for all of these will tell you what the expected parameters are, and also what parameters it may return.
CallBack Scope
Something to bear in mind when passing anonymous functions around like this is that the callback doesn’t inherit the scope of the function it’s passed into. The callback function isn’t declared inside the destination function, merely invoked from it. A callback function inherits the scope in which it’s defined.
Let’s understand this with the idea of scope circles and look at this visually in figure
Here you can see that the callback has its own local scope inside the global scope, as that’s where requestB is defined. This is all very well and good if your callback will only need access to its inherited scope, but what if you want it to be smarter? What if you want to use data from your asynchronous function in your callback? Currently the example callback function has a dollar amount hard-coded into it, but what if you want that value to be dynamic, to be a variable? Assuming this value is set in the setTimeout function, how do you get it into the callback? You could save it to the global scope, but as you know by now this would be bad. So you need to pass it as a parameter into the callback function. This should give you something like the scope circles shown in figure
This code snippet will output the same message to the console that you’ve already seen. The big difference now is that the value of dollars is being set in the setTimeout function and being passed to the callback.