Question

I have a series of ajax calls that fill columns on a page.

var doneDefers = function(defer) {
        // leftColDefer is another deferred that sets some header info
    $.when(defer, leftColDefer).done(function(req1, req2){
        var data = req1[0],
        head = req2[0];
        // spit this data out to elements on the page   

    });
};  
for(i=0;i<window.ids.length;i++){
    defer[i] =  $.ajax({
        url: 'api/get_runs_stats.php',
        type: 'GET',
        dataType: 'json',
        data: {
            run_id: window.ids[i]
        }
    });
    doneDefers(defer[i]);
}

This works fine. If an ajax call fails, nothing is spit out and all is right with the world. Now I want to do some calculations based on all the data that got spit out.

$.when.apply(null, defer)
    .done(function() {
        var args = Array.prototype.slice.call(arguments);
        calcDeltas();

    })
    .fail(function() {
        var args = Array.prototype.slice.call(arguments);
        console.log('in list fail');
    });

The done function works fine none of the ajax calls fail. If one of them fail, I go into the fail function and I don't have access to any of the return data from the other runs. The arguments array only has the failed call's data.

I would like to do my calculations on the data sets that passed. How can I get to the data from the good calls when one of them fails?

Était-ce utile?

La solution

I'm not sure this is the simplest solution but it stands a chance of working.

var ajax_always_promises = [],//to be populated with promises that (barring uncaught error) are guaranteed to be resolved.
    data_arr = [],//an array to be (sparsely) populated with asynchronously delivered json data.
    error_arr = [];//an array to be (sparsely) populated with ajax error messages.

$.each(window.ids, function(i, id) {
    var dfrd = $.Deferred();
    var p = $.ajax({
        url: 'api/get_runs_stats.php',
        type: 'GET',
        dataType: 'json',
        data: {
            run_id: window.ids[i]
        }
    }).done(function(json_data) {
        data_arr[i] = json_data;//intentionally not `data_arr.push(json_data);`
    }).fail(function(jqXHR, textStatus, errorThrown) {
        error_arr[i] = textStatus;//intentionally not `error_arr.push(textStatus);`
    }).always(dfrd.resolve);

    ajax_always_promises[i] = dfrd.promise();
    doneDefers(p);
});

$.when.apply(null, ajax_always_promises).done(function() {
    //The data in the (sparsely) populated arrays `data_arr` and `error_arr` is available to be used. 
    var i, id, success_count=0, error_count=0;
    for(i=0; i<Math.max(data_arr.length,error_arr.length); i++) {

        //Here, the index i corresponds to the original index of window.ids ...
        //...that's the advantage of sparsely populating the arrays.
        id = window.ids[i];
        if(data_arr[i]) {
            //Here, do whatever is required with `data_arr[i]`, and `id` if needed.
            success_count++;
        }
        else if(error_arr[i]) {
            //Here, do whatever is required with `error_arr[i]`, and `id` if needed.
            error_count++;
        }
    }
    console.log("Success:errors: " + success_count + ':' + error_count);
});

Untested - may well need debugging

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top