Waiting for multiple simultaneous AJAX requests to be finished has become quite easy by using the concept of Promises. We change each AJAX call to return a Promise. Promises from all AJAX calls are then passed to the Promise.all() method to find when all Promises are resolved.
Our Modified AJAX Request
A normal AJAX request using XMLHttpRequest() looks like the below.
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if(this.readyState == 4) {
if(this.status == 200)
let response = this.responseText;
else
alert('Call Failed');
}
};
xhttp.open("GET", "ajax.php");
xhttp.send();
We modify the above code so that the execution of the code returns a Promise. This Promise is resolved when the AJAX call is successful, and rejected if unsuccessful.
function ajax_call() {
return new Promise(function(resolve, reject) {
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if(this.readyState == 4) {
if(this.status == 200)
resolve(this.responseText);
else
reject('Call Failed');
}
};
xhttp.open("GET", "ajax.php");
xhttp.send();
});
}
All our AJAX requests will be similar.
Waiting Promises from Multiple AJAX Calls to Finish
Each AJAX request gives us a Promise. We then wait for all these Promises to resolve successfully using Promise.all() method.
Promise.all() also returns a Promise. This Promise is resolved successfully when all input Promises have been resolved. It is resolved with an array containing resolved values of all given Promises in order of input passed.
The return Promise from Promise.all() is rejected if one of input Promises is rejected. It is rejected with the same reason as the first rejected Promise.
Promise.all([ promise_1, promise_2 ]).then(function(values) {
// all input Promises resolved
}).catch(function(reason) {
// one of input Promises rejected
});
Final Code
// AJAX call 1
function call_1() {
return new Promise(function(resolve, reject) {
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if(this.readyState == 4) {
if(this.status == 200)
resolve(this.responseText);
else
reject('Call 1 Failed');
}
};
xhttp.open("GET", "ajax-1.php");
xhttp.send();
});
}
// AJAX call 2
function call_2() {
return new Promise(function(resolve, reject) {
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if(this.readyState == 4) {
if(this.status == 200)
resolve(this.responseText);
else
reject('Call 2 Failed');
}
};
xhttp.open("GET", "ajax2-2.php");
xhttp.send();
});
}
Promise.all([ call_1(), call_2() ]).then(function(values) {
// all AJAX requests are successfully finished
// "values" is array containing AJAX responses of all requests
console.log(values);
}).catch(function(reason) {
// one of the AJAX calls failed
console.log(reason);
});