简体   繁体   中英

Javascript: Call a function after all async calls have returned

In my project, data is distributed across groups of table. For reading the data, I need to make Async call to each of these groups (1...groupCount).

I need to call another function after all the data present in each of these groups is successfully read. What is the best way to do so?

function getData() {

    for(var gc = 1; gc < groupCount; gc++)
        readDataFromAsync(gc);

}

Assuming readDataFromAsync returns a jQuery deferred object

Use jQuery.when() and pass a callback to run when all is done.

function getData() {
  var promises = [];
  for (var gc = 1; gc < groupCount; gc++) {
    promises.push(readDataFromAsync(gc));
  }
  $.when.apply(undefined, promises).done(function(/*...*/) {
    // your code
  });
}

First of all it is a bad practice to call AJAX several time, like inside of a loop. If you can combine all the call and send all the request at a time, and take back all the response at a time then it will be best approach. For that you need to update server side code also.

But it is not possible always and depending on circumstances you need to call like this ways.

Here is some alternatives. Use synchronous call insteted of async as follows

jQuery.ajax({
    url: '.....',
    success: function (result) {
        //.....
    },
    async: false
});

But it will be slow since 1 by 1 call is there and not at all a good practice.

So you could count the ajaxResponse as a variable on your successful or unsuccessful response and call a final method when ajaxResponse reach it's cap as follows.

var ajaxResponse  = 0;
function getData() {
    ajaxResponse= 0;
    for(var gc = 1; gc < groupCount; gc++)
        readDataFromAsync(gc);
}
function readDataFromAsync(gc) {
     $.ajax(...).success() {
       //Your current code
       ajaxResponse++;
       if(ajaxResponse>=groupCount){
             finalCall();
       }
     }
}

But there is problem also for the above approach. Handling ajaxResponse counter is difficult and there could be error occurred on ajax call.

You could also try setInterval and clearInterval instated of putting one if inside the success method but it will also costly. Last one but best is approach provided by @Li Yin Kong as follows.

function getData() {
  var promises = [];
  for (var gc = 1; gc < groupCount; gc++) {
    promises.push(readDataFromAsync(gc));
  }
  $.when.apply(undefined, promises).done(function(/*...*/) {
    // your code
  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM