Callback

Edit this Page

A callback is a function which is passed as an argument to another function.

The most direct application of a callback is when a particular function is applied to a collection of values.

Some languages support a block syntax for some iterative operations (like Ruby's Array#each), whereas other languages support functions as first-class citizens, meaning that functions act like other values and can thus be passed as arguments explicitly.

(in Ruby)

numbers = [10, 20, 30, 40]

# Some callbacks can be written as unnamed blocks
numbers.each do |number|
  puts number * 2
end

# Other callbacks may be assigned to a variable before use
capitalize_word = lambda { |word| word.capitalize }
"every word should be capitalized".split(" ").map(&capitalize_word)

(in JavaScript)

var numbers = [10, 20, 30, 40];

// Some callbacks can be written as anonymous functions
numbers.forEach(function(number) {
  console.log(number * 2);
});

// Other callbacks may be assigned to a variable before use
var capitalizeWord = function(word) {
  return word.charAt(0).toUpperCase() + word.substring(1);
};
"every word should be capitalized".split(" ").map(capitalizeWord);

An additional feature of callbacks is that they do not necessarily have to be executed immediately. They can be kept for future use, which makes them a very flexible tool.

The following example shows one way in which you could use callbacks to model an emergency dispatch system, providing pre-defined actions (i.e. callbacks) to be executed when an emergency happens.

(in Ruby)

class EmergencyDispatch
  def initialize
    # Store responses to emergencies in a hash
    @responses = {}
  end

  # Register a particular response with a type of emergency
  def register(emergency_type, response)
    @responses[emergency_type] = response
  end

  # When the emergency occurs, execute the response function
  def notify(emergency_type)
    callback = @responses[emergency_type]

    raise "Don't know how to respond to #{emergency_type}, sorry" unless callback

    callback.call
  end
end

dispatcher = EmergencyDispatch.new

# Our dispatcher will be able to respond to crimes and fires
dispatcher.register("crime", -> { puts "Send the police!" })
dispatcher.register("fire",  -> { puts "Send the firefighters!" })

# When a new emergency occurs, we notify the dispatcher
dispatcher.notify("fire")
dispatcher.notify("crime")

# What happens when an unexpected event occurs?
dispatcher.notify("Godzilla")

(in JavaScript)

var EmergencyDispatch = function() {
  // Store responses to emergencies in an object
  this.emergencies = {};
}

// Register a particular response with a type of emergency
EmergencyDispatch.prototype.register = function(emergencyType, response) {
  this.emergencies[emergencyType] = response;
};

// When the emergency occurs, execute the response function
EmergencyDispatch.prototype.notify = function(emergencyType) {
  var response = this.emergencies[emergencyType];

  if (!response) {
    throw "Don't know how to respond to " + emergencyType + ", sorry";
  }

  response();
};

var dispatcher = new EmergencyDispatch();

// Our dispatcher will be able to respond to crimes and fires
dispatcher.register("crime", function() { console.log("Send the police!"); });
dispatcher.register("fire",  function() { console.log("Send the firefighters!"); });

// When a new emergency occurs, we notify the dispatcher
dispatcher.notify("crime");
dispatcher.notify("fire");

// What happens when an unexpected event occurs?
dispatcher.notify("Godzilla");