Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perform many AJAX requests in parallel, and run a function after all of them complete

I'm trying to accomplish the following sequence of operations using JQuery in HTML.

  • A list of urls is constructed
  • Each of these urls is requested using $.getJSON(url) in parallel
  • Wait for all requests to complete or to fail (404 might happen)
  • Take the data of all completed JSON-Requests and do something.

I constructed the Java-Script code posted below. It works perfecly except if one of the requests fails due to a 404-error: Then, $.when does not run because it instantly aborts if a requests fails. Can you somehow override the ajax-requests, so they don't fail but instead return a empty source?

I already read this and this post, but it does not provide a solution where code can be run after all queries have completed.

function fetchData() {
    queries = [];
    //urls is initialized somewhere else containing all urls
    for(var url in urls) {
        queries.push($.getJSON(url));
    }

    $.when.apply(this, queries).done(function() {
        console.log("Finished all queries, got "+arguments.length+" results");
        //Now arguments is a array containing the results of all requests
    }

    //function returns instantly, no problem!
 }
like image 652
theomega Avatar asked Apr 24 '11 21:04

theomega


1 Answers

I might do something like this:

$(document).ready(function(){
    var _q = ['/echo/json/', '/echo/json/', 'mybadurl'];
    var _d = [];
    for(u in _q)
    {
        $.ajax({
            url: _q[u],
            success: function(data){
                pushData(data);
            },
            error: function(x){
                pushData(x);
            }
        });
    }

    function pushData(d)
    {
        _d.push(d);
        if(_d.length == _q.length)
        {
            alert('were done');
        }
    }
});

Here, you're pushing data from either the success or error onto the array _d and testing to make sure you've received all replies before continuing (alert('were done');).

Of course, you could make this smarter by pushing an object that contains op state along with the payload into _d, but this was a quick hack together to demonstrate how I'd most likely go about doing what you're asking.

Fiddle here

like image 150
Demian Brecht Avatar answered Oct 16 '22 21:10

Demian Brecht