What is a callback?

In JavaScript, a callback is a function that is passed to another function. Since the JavaScript language facilitates passing functions to other functions as arguments, the callback can be passed around and is eventually executed by the "calling" function - the function that eventually invokes the callback. Callbacks may be executed synchronously or asynchronously.

Examples

Let's get into an example with a callback function and another function that accepts the callback and invokes it. Let's define:

  • a callback function that logs a string to the console
  • a function that receives an array of numbers and a callback as parameters (in that order), iterates over the array building up a sum of the numbers, invokes the callback after every iteration but before the next iteration and finally returns the sum of numbers
  • the array of numbers passed into the above function
function iterationFinishedCallback() {
  console.log("Iteration done")
}

function addNumbers(numbers, callback) {
  let total = 0
  for (var x = 0; x < numbers.length; x++) {
    total = total + numbers[x]
    callback()
  }

  return total
}

const numbers = [1, 2, 3, 4, 5]

console.log(addNumbers(numbers, iterationFinishedCallback))
// Iteration done
// Iteration done
// Iteration done
// Iteration done
// Iteration done
// 15

Alrighty, the callback was successfully executed 5 times! The callback in the example above is a named reference to a declared function.

Let's take a look a common callback usage - setTimeout - and pass an anonymous function to setTimeout.

window.setTimeout(function() {
  console.log("Callback called after 3000ms")
}, 3000)

// Callback called after 3000ms

Lekker! An anonymous function was passed in to setTimeout and was called after 3000ms.

We have looked at synchronous callbacks, but what about asynchronous callbacks? Let's look at an asynchronous, event-based callback.

Perhaps we want to update our user-interface with the location (x and y co-ordinates) of where the user-clicks.

// this function is responsible for updating our webpage UI
// it receives an `event` object created by the browser
function updateUi(event) {
  const xNode = document.getElementById("x-co-ord")
  const yNode = document.getElementById("y-co-ord")

  // update the DOM nodes' text
  xNode.innerText = event.clientX
  yNode.innerText = event.clientY
}

// if we attach an event "listener" to the body node
// and listen for "clicks", the browser will handle
// calling our `callback` in response to user
// click events.
const body = document.getElementsByTagName("body")[0]
body.addEventListener("click", updateUi)

// now if the user clicks anywhere on the body, the page will
// display the X and Y co-ordinates of where the user clicked.

So, to wrap up, a callback is any function that is passed to another function as an argument and is executed. Bear in mind that the callback may be passed around before being executed. A callback can be executed synchronously or asynchronously.

History

Since JavaScript's early days callbacks have been supported because JavaScript supports first-class functions - functions that can be passed to other functions as arguments, functions that can be assigned to variables and functions that can return functions!