Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make batches of ajax requests in jQuery?

Tags:

jquery

ajax

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.

like image 435
stinkycheeseman Avatar asked Aug 08 '11 18:08

stinkycheeseman


People also ask

Can we execute run multiple AJAX requests simultaneously in jQuery?

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.

How do I send AJAX requests every second?

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);

Can I make AJAX requests by jQuery?

jQuery ajax() Method. The jQuery ajax() method provides core functionality of Ajax in jQuery. It sends asynchronous HTTP requests to the server.

Can a page make more than one AJAX request?

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.


3 Answers

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.

like image 135
Garett Avatar answered Sep 28 '22 13:09

Garett


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);      
   });
}
like image 30
spdeveloper Avatar answered Sep 29 '22 13:09

spdeveloper


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.

like image 21
Benjamin Atkin Avatar answered Sep 26 '22 13:09

Benjamin Atkin