378 CHAPTER 8 Websites and services
When you use jQuery to execute an AJAX call, a promise object is returned. Think of a
promise as being a promise to do work. The promise object enables you to register a call-
back method to execute when the AJAX call is successful, has failed, is progressing, and has
completed. The promise object has the following methods that you can use to register called
functions.
■■always() Add handlers to be called when the AJAX call has completed, regardless of
whether it was successful
■■done() Add handlers to be called when the AJAX call is successful
■■fail() Add handlers to be called when the AJAX call has failed
■■progress() Add handlers to be called when the AJAX call generates progress
notifications
The following code demonstrates the refactoring of the addNumbers function to use the
promise that’s returned from the AJAX call.
function addNumbers() {
var data = getFormData();
serverAddition(data).done(displayResult);
}
function getFormData() {
var x = $('#x').val();
var y = $('#y').val();
return { "x": x, "y": y };
}
function serverAddition(data) {
return $.getJSON('/addition', data);
}
function displayResult(serverData) {
$('#result').html(serverData.result);
}
So what happened here? It looks like the code grew in size, and in some respects, it did,
but the code got cleaner, too. The serverAddition function handles the AJAX call to the server
but does not attempt to handle the results. Instead, the serverAddition function returns a
promise object, and the caller can decide how to handle the result.
The addNumbers function is responsible for collecting the data to pass to the serverAddi-
tion function and deciding how to process the result. To collect the data, a call is made to the
getFormData function that collects the data and creates an object that can be used for the
AJAX call. The data object is passed to the serverAddition function. The returned promise is
used by chaining a call to the done method. The done method requires a function param-
eter, which can be an anonymous function as in the previous examples, or you can pass the
name of a function as in the example where the displayResult function is specified. Creating
a specific function enables the other functions to call the displayResult function, which helps
promote code reuse. The following is the default.js file after refactoring the other functions.