Click here to Skip to main content
15,867,704 members
Articles / Programming Languages / Javascript

Waiting For Multiple Ajax Requests - jQuery

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
13 Apr 2017CPOL3 min read 41.3K   13   1
Write jQuery code to wait for multiple Ajax requests

Introduction

Usually, jQuery function ajax is used to make an Ajax call. Function ajax can only make one Ajax call. A callback function is executed when the Ajax call is successful. Optionally, another callback function is called when the Ajax call returns an error. However, this function can not make multiple Ajax requests and register callback functions based on the outcome of these requests. One scenario is that a web page makes multiple Ajax requests to gather data for different sections of the page while disabling user interaction. The page enables user interaction only after the page gets all data. This article describes a method provided by jQuery to register a callback function based on multiple Ajax requests. This method is based on the concept of Deferred object.

Using the code

First, two ASP.NET Web API functions are used to accept server Ajax calls.

JavaScript
public class ValuesController : ApiController
{
    // GET api/values
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/values/5
    public string Get(int id)
    {
        string s = "Id is " + Convert.ToString(id);
        return s;
    }
}

To make a single Ajax call, jQuery function ajax can be used. Here is a simple example.

JavaScript
$.ajax({
    url: 'api/values',
    dataType: 'json',
    type: 'GET',
    success: function (data) {
        alert(data[0]);
    },
    error: function () {
        alert('Error!');
    }
});

The success and error callback functions are waiting for a single Ajax call.

The jQuery library provides a way to make any callback function waiting for multiple Ajax calls. This method is based on an object called Deferred.

A Deferred object can register callback functions based on whether the Deferrred object is resolved or rejected. Here is an example of the Deferred object.

JavaScript
// Create a Deferred object.
var def1 = $.Deferred();
// Add a function to be called when the Deferred object is resolved.
def1.done(function (data) {
    alert(data);
});
// Resolve the Deferrd object.
def1.resolve('Resolved!');

// Create a Deferred object.
var def2 = $.Deferred();
// Add a function to be called when the Deferred object is rejected.
def2.fail(function (data) {
    alert(data);
});
// Reject the Deferrd object.
def2.reject('Rejected!');

Note the Deferred object can be chained. Here is an example of the Deferred object chain.

JavaScript
var def = $.Deferred();
def.done(function (data) {
    alert(data);
}).fail(function (data) {
    alert(data);
});
// Reject the Deferrd object.
def.reject('Rejected!');

The Deferred object has a method called promise. It returns a Promise object. A Promise object exposes a subset of Deferred methods to prevent its state to be changed. That means, to prevent the Deferred object to be resolved or rejected manually. A Promise object exposes the following Deferred methods:

then, done, fail, always, pipe, progress, state and promise.

It does not expose the following Deferred methods:

resolve, reject, notify, resolveWith, rejectWith and notifyWith.

A Promise object can be treated as a Deferred object which state cannot be manually changed.

The jQuery ajax function returns a jqXHR object. There are two important facts about this jqXHR object.

First, a jqXHR object is a superset of XMLHTTPRequest object. For example, a jqXHR object can query the state of the XMLHTTPRequest by referring its readyState property. If its readyState is 4, the Ajax request is completed.

Second, a jqXHR object implements the Promise interface and exposes all Promise methods. Basically, a jqXHR oject can be treated as a Promise object. For example, the done method can be used as the success callback function for a jqXHR object.

The jQuery library provides a function called when to accept multiple Deferred objects and returns a Promise object. The returned Promise object will be resolved when all Deferred objects are resolved. It will be rejected when any Deferred object is rejected. The Deferred objects passed to function when can be Deferred objects, Promise objects or jqXHR objects.

Here is an example of code waiting for multiple Ajax requests.

JavaScript
$(document).ready(function () {
    var j1 = $.ajax({
        url: 'api/values',
        dataType: 'json',
        type: 'GET'
    });

    var j2 = $.ajax({
        url: 'api/values',
        dataType: 'json',
        data: { id: 5 },
        type: 'GET'
    });

    $.when(j1, j2).then(function (a1, a2) {
        alert('Both j1 and j2 succeedeed!');
    }, function (jqXHR, textStatus, errorThrown) {
        var x1 = j1;
        var x2 = j2;
        if (x1.readyState != 4) {
            x1.abort();
        }
        if (x2.readyState != 4) {
            x2.abort();
        }
       alert('Either j1 or j2 failed!');
    });
});

First, two variables store the jqXHR objects returned from two jQuery Ajax calls. Then the two objects are passed to function when. The Promise object returned from when is chained to function then. Function then adds handlers for the Promise object. The first parameter of function then is a success function which is called when the Promise is resolved. The second parameter of function then is a fail function which is called when the Promise is rejected. The fail function checks the state of each Ajax call. If the Ajax call is not completed, it is aborted. Note the fail function can still access variable j1 and j2 which are out of scope since the document ready function has been
executed and closed. This is because of JavaScript closures. A closure is an inner function which has access to variables in outer function even the outer function is closed. In other words, the inner function can keep the environment in which it is first defined.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Canada Canada
I am working with ASP.NET related technologies.

Comments and Discussions

 
Questionout-@#$%ing-standing! Pin
Member 123628499-Sep-18 19:22
professionalMember 123628499-Sep-18 19:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.