Platinum Partner
css,javascript,tips and tricks

Cleanup Your jQuery by Deferring

The asynchronous nature of AJAX sometimes makes jQuery code a bit hard to follow. Embedding callbacks in AJAX calls starts off reasonable, but enough callbacks can quickly become unwieldy.

If your code base is suffering from this issue, have a look at the jQuery Deferred API. jQuery Deferred is an implementation of the CommonJS Promises Spec.

The CommonJS Promises Spec attempts to put an API around the consistent pattern of handling asynchronous callbacks. In the case of jQuery Deferred we are generally talking about AJAX calls. Let’s look at an example that will help to clarify the scenario.

Traditional Approach

Let’s say you have two services you are invoking to show information on a map. One service provides the latitudinal and longitudinal coordinates (geolocation) of an address, while another service provides nearby businesses.

function findGeolocation(address){
    $.ajax({
      url: "/echo/json/",
      data: {json: JSON.stringify({"address" : address})},
      type: "POST",
      success: function(geolocation) {
        findNearbyBusinesses(address, geolocation);
      }
  });
}

function findNearbyBusinesses(address, geolocation){
    $.ajax({
      url: "/echo/json/",
      data: {json: JSON.stringify({"address" : address})},
      type: "POST",
      success: function(businesses) {
        showLocationMap(geolocation, businesses);
      }
}

It’s difficult to follow the control structure of the above code due to the embedded callbacks. The $.when method from the jQuery Deferred API helps clean this up.

Using jQuery Deferred

Instead of embedding our control flow in the callback functions themselves, we can specify the flow through an API. The $.when method accepts a list of functions that return a Deferred object. The $.ajax API returns a Deferred object allowing us to directly pass the result of AJAX invocations to the $.when method.

Once an AJAX request completes, the Deferred object is considered “done”. The $.when method waits for all Deferred objects to reach the “done” state and then invokes any handler functions that have been specified for the following:

  • done – handlers always called once all Deferred objects complete
  • then – handlers called if all Deferred objects complete successfully
  • fail – handlers called if a failure occurs with one of the Deferred objects

Now let’s rewrite our above code snippet to use the $.when API.

function findGeolocation(address){
    return $.post(
        "http://solutionsfit.com/geolocate",
        {json: JSON.stringify({"address" : address})}
    );
}

function findNearbyBusinesses(address){
    return $.post(
        "http://solutionsfit.com/nearbyBusinesses",
        {json: JSON.stringify({"address" : address})}
    );
}

$.when(findGeolocation(address), findNearbyBusinesses(address))
    .then(function(geolocation, businesses) {
        showLocationMap(geolocation, businesses);
    });

Notice that the readability now clearly defines the control flow. This now reads as:

when we find the geolocation and any nearby businesses, then show the location and businesses on a map

In addition, in the second case we’ve improved performance by allowing our AJAX calls to execute simultaneously. In the first case, the retrieval of nearby businesses was forced to wait on the geolocation call due to the embedded callback.

There is much more to the API and you can review all the details here.

Published at DZone with permission of {{ articles[0].authors[0].realName }}, DZone MVB. (source)

Opinions expressed by DZone contributors are their own.

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}