Javascript: is there a better way to execute a function after x sum of async database / ajax calls

using Backbone.js we have an application where at some point we need to send an ajax message to the client webservice.

however, the content to be published is dynamic and defined by a specific array.

for each element of the array, we need to perform a data selection.

after collecting the data to be sent by the aggregated object.

I have a synchronous approach at the moment, although I think this is not the best way.

var arrParams = [{id: 1, processed: false},{id: 7, processed: false},{id: 4, processed: false}];

function callback(data) {
    $.post()... // jquery ajax to post the data... }

function fetchData(arr, data, callback) {
    var currentId = _(arr).find(function(p){ return p.processed === false; }).id;  // getting the ID of the first param that has processed on false...

    // ajax call fetching the results for that parameter.
    $.ajax({
        url: 'http://mysuperwebservice.com',
        type: 'GET',
        dataType: 'json',
        data: {id: currentId},

        success: function(serviceData) {
            data[currentId] = serviceData;  // insert it into the data
            _(arr).find(function(p){ return p.id === currentId; }).processed = true; // set this param in the array to 'being processed'.
            // if more params not processed, call this function again, else continue to callback
            if(_(arr).any(function(p){ return p.processed === false }))
            {
                 fetchData(arr, data, callback);
            }
            else
            {
                callback(data);
            }
        },
        error: function(){ /* not important fr now, ... */ }
    }); 
}

fetchData(arrParams, {}, callback);

      

is there no way to start these asynchronous calls and execute the callback only when all the results are in?

+2


source to share


2 answers


You need to use a JQuery object to keep $.Deferred

them in sync. Take a look at this article Deferred Documents

You can use like this:



$.when(
   $.ajax({ url : 'url1' }),
   $.ajax({ url : 'url2' }) // or even more calls
).done(done_callback).fail(fail_callback);

      

+8


source


I would do something like this:

make a function that, in addition to the parameters you pass to fetchData, also gets the index in arrParams, and then in a loop calls this function for each element. In the success function set handled on your element, set to true and check "if you are the last" by going through the array and see if all the others are true.

A bit of optimization could be if you create a counter:



var todo = arrParams.length;

      

and in successful execution:

if (--todo == 0) {
   callback(...)
}

      

0


source







All Articles