- Explain what a callback is
- Explain how callbacks are used in JavaScript
- Practice writing functions that take callbacks
When I was your age, I had a boat.
It was not a fancy boat or a particularly nice boat, but it was my boat.
Boats, as you know, have many moving parts. And these parts need to be cleaned.
Now, I could have cleaned every part separately, iterating through the piles of barnacle-encrusted tools one by one, preparing to clean each individual piece with a bit of a care.
Or I could get a bit smarter about it. I could prepare once for each group of related items, so that I wouldn't have to prepare to clean each item individually. In code, that might look like:
function clean(item) {
console.log(`I just cleaned a ${item}`)
}
var nails = ["rusty nail", "rusty nail", "bent nail", "clean nail"]
for (var i = 0; i < nails.length; i++) {
clean(nails[i])
}
var planks = ["splintered plank", "straight plank", "bent plank"]
for (var i = 0; i < planks.length; i++) {
clean(planks[i])
}
console.log('done!')
And so on and so forth. Well now, this wasn't so bad, but I noticed that I was preparing to clean everything — and cleaning everything, really — in the same way. What if I could just group all of the things that I needed to clean, and prep for the cleaning once?
function groupAndClean(items, cleaningMethod, done) {
for (var i = 0; i < items.length; i++) {
cleaningMethod(items[i])
}
done()
}
groupAndClean(nails.concat(planks), clean, function() {
console.log('Whew, that was a lot of work!')
})
So went the days of my youth, when I learned to pass functions as arguments to other functions.
And my boat was cleaner for it.
In JavaScript, we have the ability to pass functions as arguments. This makes it really easy to abstract functionality out of our programs, making the programs easier to reason about by breaking them into smaller chunks.
For example, let's say we have a function that lets us do anything we want to the number 5 (follow along in the browser's console!):
function doTo5(anything) {
return anything(5)
}
Well, let's try it out. Can we divide with it?
function divide10ByN(n) {
return 10 / n
}
doTo5(divide10ByN) // 2
Cool, cool. Can we append it to a string?
function appendToHello(s) {
return `Hello, ${s}!`
}
doTo5(appendToHello) // 'Hello, 5!'
Some things to note:
-
neither
divide10ByN()
norappendToHello()
knows that it's going to receive5
specifically — these functions only know that they're going to receive an argument. They're very generic. -
We do not call
divide10ByN
orappendToHello
when we pass them as functions todoTo5()
— that is, we pass just their name without any parentheses after it. That's because the calling actually happens insidedoTo5()
, whendoTo5()
calls back to the "outside world." Because of this process of calling back, we often call functions that we pass to other functions callbacks.
Callbacks can also be useful for when we finish an expensive operation and want to return to a previous function's context (similarly to how done()
was used in the boat example).
function somethingExpensive(callback) {
// do something crazy,
// like fetching a bajillion websites
// then pass their data to callback:
// (supposing that we have defined `data`
// along the way)
callback(data)
}
View Javascript Callbacks on Learn.co and start learning to code for free.