Jquery отложено - дождитесь завершения двух вызовов

Я ищу способ сделать обратный вызов после завершения двух вызовов ajax:

$.when(
    call1(),
    call2()
).always(function() {
    // Here I want to be sure the two calls are done and to get their responses 
);

Ловушка заключается в том, что один из вызовов может выйти из строя. Таким образом, в моем коде всегда вызывается без ожидания другого вызова.

Как я могу ждать выполнения обоих вызовов (успех или сбой)?

Ответ 1

Вот что должно было сделать трюк:

$.whenAllDone = function() {
    var deferreds = [];
    var result = $.Deferred();

    $.each(arguments, function(i, current) {
        var currentDeferred = $.Deferred();
        current.then(function() {
            currentDeferred.resolve(false, arguments);
        }, function() {
            currentDeferred.resolve(true, arguments);
        });
        deferreds.push(currentDeferred);
    });

    $.when.apply($, deferreds).then(function() {
        var failures = [];
        var successes = [];

        $.each(arguments, function(i, args) {
            // If we resolved with `true` as the first parameter
            // we have a failure, a success otherwise
            var target = args[0] ? failures : successes;
            var data = args[1];
            // Push either all arguments or the only one
            target.push(data.length === 1 ? data[0] : args);
        });

        if(failures.length) {
            return result.reject.apply(result, failures);
        }

        return result.resolve.apply(result, successes);
    });

    return result;
}

Просмотрите эту скрипту, чтобы узнать, как это работает.

В принципе, он ожидает, что все Отсрочки закончатся независимо от того, сбой или нет, и собирает все результаты. Если у нас есть сбои, возвращаемый Deferred завершится неудачей со списком всех сбоев и разрешит все успехи в противном случае.

Ответ 2

Это некрасиво, но вы можете иметь глобальную "завершенную" переменную для каждого вызова ajax для установки после завершения. Каждый вызов также проверяет, были ли установлены обе переменные, и если да, вызовите свою всегда функцию.

Ответ 3

Вы также можете вложить вызовы:

$.when(call1()).always(function(){
    $.when(call2()).always(function(){
        // Here I want to be sure the two calls are done and to get their responses
    });
});

Но, конечно, оба вызова станут синхронными друг с другом.