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.
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
.
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.