Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for async ajax requests to finish

I'd like to write a function which performs a dozen async ajax requests, wait for all of then to finish and then return aggregated info. Like:

function countHealthy(urls) {
  var healthy = 0;
  for (var i = 0; i < urls.length; ++i) {
    $.ajax({url: urls[i], async: true, id: i})
    .done(function (data) { ++healthy; });
  }
  // Wait for all ajax to finish.
  return healthy;
}

PS: Is the ++healthy thread safe?

like image 821
Igor Gatis Avatar asked Apr 05 '13 11:04

Igor Gatis


2 Answers

Javascript doesn't have threads so thread safety is not an issue. Your return statement is the problem, it needs to go in the callback that the ajax calls execute on completion. Since ajax happens asynchronously, as your code stands, the return statement will fire before all the requests return.

You might want to check out query deferreds, which seems to be born for this type of thing. Directly from that link

function doAjax() {
  return $.get('foo.htm');
}

function doMoreAjax() {
  return $.get('bar.htm');
}

$.when( doAjax(), doMoreAjax() )
  .done(function() {
    console.log( 'I fire once BOTH ajax requests have completed!' );
  })
  .fail(function() {
    console.log( 'I fire if one or more requests failed.' );
  });

With some minor refactoring you could implement this in about 2 minutes.

Alternatively, if you control the server, you could create a server endpoint that does all the checking in one request.

like image 79
hvgotcodes Avatar answered Oct 19 '22 04:10

hvgotcodes


You can do this:

var urls= ['url1', 'url2', 'url3', 'url4'];
function doTheUrl() {
    if (urls.length === 0) {
        alert('All urls are done now.');
        return;
    }

    var url = urls.pop();
    $.ajax({
        url: "/DoTheJob",
        complete: function () {
            doTheUrl();
        }
    });
};
like image 29
Catalin Avatar answered Oct 19 '22 03:10

Catalin