liveBook · Manning

Callback

As explained in Secrets of the JavaScript Ninja, Second Edition

A function supplied to other code to be invoked later when a condition or event occurs.

A callback is a function supplied to other code so that code can invoke it at an appropriate point. JavaScript makes this possible because functions can be passed as arguments. “Later” does not necessarily mean asynchronous: an array operation might call its callback while it runs, whereas a browser event handler waits for an event. section 3.1.1 section 3.1.2

Pass the function, then call it

function run(callback) { return callback(); } function getText() { return "Hello"; } run(getText); // "Hello" Pass getText, not getText(): the first gives run a function to invoke; the second gives it the function’s result. section 3.1.2

Where callbacks earn their keep

  • Register a function with addEventListener to react to a browser event, or pass a comparison function to sort to control an array’s order. section 3.1.2
  • Pass a function to a long-running request so the UI need not wait for the result. The callback runs when the task finishes. section 6.3.1
  • Pass success and failure callbacks to a promise’s then method to handle resolution or rejection. section 6.3

Callbacks often need information from their surroundings. A timer callback can use a closure to retain an element, a counter, and a timer reference across animation steps. Keeping those variables inside the animation function gives each animation its own state instead of making multiple animations share globals. section 5.2.2

Listing 5.4. Using a closure in a timer interval callback
<div id="box1">First Box</div>                                #A
<script>
  function animateIt(elementId) {
    var elem = document.getElementById(elementId);            #B
    var tick = 0;                                             #C
    var timer = setInterval(function(){                       #D
      if (tick < 100) {                                       #E
        elem.style.left = elem.style.top = tick + "px";       #E
        tick++;                                               #E
      }                                                       #E
      else {
        clearInterval(timer);


        assert(tick === 100,                                  #F
               "Tick accessed via a closure.");
        assert(elem,
               "Element also accessed via a closure.");
        assert(timer,
               "Timer reference also obtained via a closure." );
      }
    }, 10);                                                    #G
  }
  animateIt("box1");                                           #H
</script>

The timer callback updates an element through variables retained from its enclosing animation function. section 5.2.2

Watch two traps. First, a callback’s this may not be the object whose method you passed: an event callback can receive the event-raising element as its context instead. When invoking a callback yourself, call or apply can set its context explicitly. Second, try-catch around the start of an asynchronous request generally cannot catch errors arising when its callback runs in a later event-loop step. Error arguments are one convention; deeply nested, dependent callbacks can still make control flow and error handling hard to follow. Promises and generators offer an alternative for that case. section 4.2.4 section 6.3.1 section 6.4

How Secrets of the JavaScript Ninja, Second Edition covers it

How deep it goes
Defines callbacks through invocation flow and works through closures, function context, and asynchronous error-handling pitfalls.
Examples
Shows a passed function being invoked, an animation timer retaining state, and nested JSON requests with error arguments.
What it assumes
Assumes familiarity with JavaScript functions while teaching from the basic act of passing and invoking one.
What you can do after
Build it from scratch as a function parameter, then apply it to events, collection operations, and asynchronous results.
How it connects
Connects callbacks to first-class functions, closures, browser events, array sorting, promises, and the event loop.

Also explained in

Compare how 19 books explain callback →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Secrets of the JavaScript Ninja, Second Edition. The section links point to the parts of the book it draws on.