User interaction: callbacks and forms

Callbacks

Javascript runs our code, and that code has to run quickly and terminate, because while our code is running, the browser is unresponsive. That’s why infinite while or for loops are problematic in Javascript.

What if we want to write some code to be executed later on? For example, what if we wanted to write a clock that printed out the number of seconds that elapsed, once each second? So far, that should seem impossible, since our program runs once, and is long terminated one second from now, or two seconds from now, or a thousand.

So far, we’ve defined functions and then run them immediately. But Javascript lets us define a function, and then specify that this function should be run later, under some specific circumstances.

The provided Javascript function setTimeout takes two parameters: a reference to a function to be run later, and the number of milliseconds to wait before running that function:

The function surprise has been set as callback function: we specified that Javascript should call it later, under some specific circumstances.

This is a much different programming paradigm than we have seen so far. So far, you wrote a program, Javascript executed it, with the program counter marching merrily through the code one line after another. That still happens the first time your code is run, but with the ability to register callback functions for later use, the later executions are a bit trickier to predict.

If you write a website with buttons for a customer to click, you want some code to be run when they click a button: a callback. If you want to write a fancy animation, that animation will have to draw something new every few milliseconds: a callback. If you want to update stock prices live and show them on your website, you need to write a callback to fetch stock prices from some other site every few seconds. If you want to show current weather, you’ll need to write code that checks the weather every hour. Callbacks are important.

It’s important to understand that callbacks are not magic: there is still just one single program counter (this is only mostly true), and callbacks are processed in the order they are triggered. So callback functions, like your original Javascript code, have to do their work quickly and terminate. No infinite loops inside your callback functions!

Let’s see how we could write a clock program that counts from 10 down to 1 and prints “blastoff”. You might think there would be a loop, but there won’t be. Instead, we’ll write a function that is called every one second, and updates a counter variable, prints something on the screen, and registers the next call.

We call the construction in which the countdown function calls and registers itself as a callback a chained callback, and it is quite a good way to get something that behaves like an infinite loop in Javascript, without taking over all processing power or hogging the program counter.

Notice that if you run the code a second time before the countdown has terminated, the countdown gets jumbled, since each program is interleaving chained callbacks.

Callback functions and events

The examples so far are not very dynamic; the Javascript code runs, and changes something, but that all happens before the user even has a chance to see it. What if we wanted to make a page with content that really changes over time?

There is a function setInterval that instructs the browser to call a function repeatedly every so often. setInterval takes two parameters: the name of the function to call (without parentheses), and the number of milliseconds to wait before each call.

In the next example, setInterval instructs the browser to call the updateTime function every 1000 milliseconds.

We call updateTime in the last example a callback function because setInterval instructs Javascript to call it (back) every time a certain event occurs. In this case, the event is that 1000 milliseconds have elapsed. You can give any name you like to your callback functions; you just need to tell Javascript what they are and when they should be called by calling functions like setInterval.

Buttons

By combining HTML and Javascript, you can set up an entire user interface for a fairly complicated program, all right in the browser: a web application. For example, c9.io provides a full-featured editor for code; the interface is constructed using HTML, Javascript, and CSS. Social networking sites like Facebook piece together hundreds of interface components into a larger whole. Google Docs builds traditional desktop spreadsheet and word processing into a browser. Even the small code examples on this page are constructed automatically by Javascript code that searches through the document for certain div elements, inserts some special HTML code at those locations, and loads in sample code from a file.

To build a web application, we need some ways to respond to user input. We can attach callback functions to user input events. The simplest example is a button element in HTML, with a callback bound to the onclick event.

Notice that rather than simply using name of the function to register the callback, as with setInterval, the value of the onclick attribute of the button is a string containing some Javascript code to run; that string just happens to contain a function call. Conceptually, the clicked function is still being used as a callback.

You might wonder why we created a clicked function at all in the last example. We could have just put code to call alert into the onclick attribute directly, but the code would have been harder to read.