jQuery Deferred — ожидание завершения всех динамических асинхронных запросов, даже если некоторые из них завершились неудачно

Я получил динамический асинхронный запрос (для jsfiddle я использовал ajax), который мне нужно ждать независимо от успеха или неудачи, а это значит, что мне нужно только знать, что все процессы завершены, даже если какой-то запрос не удался.

//Динамический: в моем случае это создается запросом ajax, поэтому количество последующих асинхронных запросов может быть гибким

Итак, я изначально использовал этот код:

    $.when.apply($,deferreds).done(function() {
        $("div").append("<p>All done!</p>");
    }).fail(function(){
        $("div").append("<p>Something failed!</p>");
    });

Но в случае, если один из отложенных вызовов не удался, обратный вызов сбоя будет вызван немедленно. Я попытался изменить его на always(), но результат таков:

Uncaught TypeError: Объект # не имеет метода «всегда»

Итак, как я могу реализовать для этого решение типа always()?

Скрипка

Мой исходный источник: jQuery Deferred - ожидание завершения нескольких запросов AJAX


person Marl    schedule 13.02.2013    source источник
comment
Я бы предложил использовать пользовательское отложенное выполнение, которое подсчитывает успех и неудачу, а затем разрешается в конце, хотя .always также должно работать здесь.   -  person Kevin B    schedule 13.02.2013
comment
Так? jsfiddle.net/marlberm2014/ekGeA/4   -  person Marl    schedule 13.02.2013


Ответы (2)


Если вы просто хотите дождаться окончания списка $.Deferred независимо от того, являются ли они rejected или resolved, у вас есть решение в моем ответе в исходном источнике jQuery Deferred — ожидание завершения нескольких запросов AJAX :

$.when.apply($, $.map(deferreds, function(d) {
    var wrapDeferred = $.Deferred();
    // you can add .done and .fail if you want to keep track of each results individualy
    d.always(function() { wrapDeferred.resolve(); });
    return wrapDeferred.promise();
}));
person Mordhak    schedule 14.02.2013
comment
Блин, ответ уже есть в источнике. 0_0 не видел. Спасибо за ответ. - person Marl; 14.02.2013
comment
Большое спасибо за это, я на самом деле не кодер Javascript, и это спасло мне жизнь! Знаете ли вы, как я могу понять, какие из них сработали, а какие нет (и почему)? - person LaughingJohn; 11.03.2013
comment
Вам не хватает закрывающей скобки в последней строке, должно быть })); - person Chloraphil; 07.08.2013

Хорошо, как предложил Кевин Б. Я использовал пользовательскую отсрочку, которая будет разрешена независимо от результата асинхронного запроса.

var deferreds = $.map(i, function (count, index){
    var waitingProcess = new $.Deferred(); //Here is the custom deferred
    if(count == 7) {
        $.Deferred().fail(function(){
            $("div").append("<p>Task #" + count + " failed.");
            waitingProcess.resolve(); //resolve it no matter the outcome
        }).reject();
    }else{
        $.post('/echo/html/', {
            html: "<p>Task #" + count + " complete.",
            delay: count
        }).success(function(data) {
            $("div").append(data);
            waitingProcess.resolve(); //resolve it no matter the outcome
        });
    }
    return waitingProcess.promise();
});

Скрипка

person Marl    schedule 13.02.2013
comment
Откуда взялось это волшебное число 7? можно ли вместо этого рассчитать? - person Kevin B; 13.02.2013
comment
Он только моделирует случай, когда один из запросов не удался. - person Marl; 13.02.2013