I'm wondering how to make ajax calls in groups of n.
Here's my use case:
I have a table that displays usage data. You can drill into each row, and if each row has a common attribute you can drill deeper into, you can choose to drill into all of them at once. For each row, an ajax call is made to fetch the data to be appended to the table.
In certain cases there can be up to 50 rows to drill into simultaneously. As you can imagine, that puts a lot of stress on the server. How best can I send these calls in smaller batches that wait on the batch before them to fire off?
I know there are plugins like jquery message queuing that could potentially help me out, but this is a work project so we'd like to avoid plugins as much as possible.
To iterate through the response, there is a callback function attached to it. This callback function gets executed once both the Ajax requests are finished. In case where multiple Deferred objects are passed to $. when() , it takes the response returned by both calls, and constructs a new promise object.
ajax({ type: 'POST', url: 'increment. php', data: $(this). serialize(), dataType: 'json', success: function (data) { $('#hidden'). val(data);// first set the value }, complete: function (data) { // Schedule the next setTimeout(doAjax, interval); } }); } setTimeout(doAjax, interval);
jQuery ajax() Method. The jQuery ajax() method provides core functionality of Ajax in jQuery. It sends asynchronous HTTP requests to the server.
There is a requirement to make multiple AJAX calls parallelly to fetch the required data and each successive call depends on the data fetched in its prior call. Since AJAX is asynchronous, one cannot control the order of the calls to be executed.
You can take a look at using jQuery.when, which allows you to execute callback functions when all requests have completed.
$.when($.ajax("request1"), $.ajax("request2"), $.ajax("request3"))
.done(function(data1, data2, data3){
// Do something with the data
});
Or
$.when($.ajax("request1"), $.ajax("request2"), $.ajax("request3"))
.then(successCallback, errorHandler);
See the following post for more information.
Also, I'm not sure that your apprehension towards using a plugin should be affected by the fact that you are in a work environment, especially if it simplifies your work. Hence allowing to be more productive. Granted you have to choose your plugins carefully, since quality and long term maintenance can be a issue.
Ajax calls using jQuery are typically asynchronous. So, if you have 50 rows, jQuery will asynchronously send all 50 requests--you don't get to control the sequence of processing when you get responses from the server.
You can use async: false
on the $.ajax
call such that only one request is sent to the server as you loop through your rows:
$.ajax({
url: location,
data: params,
async: false,
success: function(msg) { // do something}
});
The issue with this approach (async: false
) is that user may experience a "freeze" or unresponsive page.
Another way is to use recursion in your JavaScript so that the calls are still asynchronous but the ajax call still waits for the success event of each row like the following:
var maxRows = 50;
function myFunc(index) {
$.ajax({
url: location,
data: params,
async: true,
success: function(msg) {
if (index < maxRows) {
// do something
}
else {
return; //index equals maxRows--stop the recursion
}
index++;
myFunc(index); //call the function again
}
});
$(document).ready(function() {
myFunc(0);
});
}
I agree with eicto: make your own message manager if you can't integrate another one. Here's my crack at a tiny one:
var AjaxQueue = function(max) {
this.max = max;
this.requests = [];
this.current = 0;
}
AjaxQueue.prototype.ajax = function(opts) {
var queue = this;
opts.complete = function(jqXHR, textStatus) {
queue.current -= 1;
queue.send();
};
this.requests.push(opts);
this.send();
}
AjaxQueue.prototype.send = function(opts) {
while (this.current < this.max && this.requests.length > 0) {
$.ajax(this.requests.unshift());
this.current += 1;
}
}
I haven't tried using it yet, so there are bound to be bugs. Also it assumes you aren't using a complete
option. It just overrides it. If you are you could check for it and make sure the previous complete function(s) still get called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With