Cris
Cris

Reputation: 5007

Execute dynamic number of ajax request sequentially

Have the following scenario :

I have to display the graphs for a given interval (startDate,endDate)

Because the interval might be quite big , the data is retrieved per day so I need to do multiple ajax calls sequentially and to append the data to the graph(highcharts)

Example interval is n days ==>

ajax request day 1 

when is (done) ready ajax request day 2

when is (done) ready ajax request day 3

....

ajax request day n

I read about deferred and promises BUT I found difficult to with dynamic number of days and the requirement to get the responses sequentially

Thanks

Upvotes: 1

Views: 2356

Answers (4)

aaronofleonard
aaronofleonard

Reputation: 2576

If you're able to store the list of dates in an array, you can use something like this:

var items = ['Apple', 'Orange', 'Banana', 'Alphalpha'];

//replaceable with any function that returns a promise
function asyncFunction(item) { 
  return $.ajax({
    url: '/echo/html',
    type: 'POST',
    data : item
  })
  .then(function(data){
    $('body').append('<div>Got the response from '+item+'</div>');
    //stuff stuff stuff
  });
}

function sequence(arr, callback) {
  var i=0;

  var request = function(item) {

    return callback(item).then(function(){

      if (i < arr.length-1)
            return request(arr[++i]);

    });
  }

  return request(arr[i]);
}

sequence(items, asyncFunction).then(function(){
    $('body').append('<div>Done with all!</div>');
});

https://jsfiddle.net/7ojy9jnx/2/

Basically, sequence takes an Array of items and runs a function on all of them (in this case asyncFunctions, which can be replaced with any function), a function that returns a promise.

This is very basic implementation, you'll notice, for example, it has no error handling. Libraries like async.js have an exhaustive list of tools that accomplish tasks like this, but who knows, maybe this will suffice.

Upvotes: 3

Matt Diamond
Matt Diamond

Reputation: 11696

Not sure if you already figured it out, but a good way to tackle your problem would be using a combination of jQuery.Deferred and recursion. Check out this sample code and see if it helps clarify things:

function getData(dayLimit) {
  var allDone = $.Deferred();

  var getDataForDay = function(day) {
    doAsyncThing(day).done(function() {
      if (day < dayLimit) {
        getDataForDay(day + 1);
      } else {
        allDone.resolve();
      }
    }).fail(function(){
      /*
        Reject the deferred if one of your operations fails.
        Useful if you're binding "fail" or "always" callbacks
        to the promise returned by getData.
      */
      allDone.reject();
    });
  };

  getDataForDay(1); //start with first day

  return allDone.promise();
}

Let me know if you need more clarification, happy to help!

Upvotes: 2

srinath
srinath

Reputation: 54

What about recursively calling. Create a parameterized function and pass the day to the function like,

function getDetails(day) {

//  ajax call
//  In the callbacks call the getDetails function by updating the date

}

Upvotes: 0

LazyDeveloper
LazyDeveloper

Reputation: 619

If you are using Jquery in your Application try pushing all the ajax to an array

ex [ajax,ajax,...]

and then user

$.when([ajax,ajax,...]).then(function(){
 console.log(arguments);// you will get the success messages in arguments array 
})

Upvotes: -1

Related Questions