Есть ли аналог «наконец» в вызовах jQuery AJAX?

84

Есть ли аналог Java "finally" в вызовах jQuery AJAX? У меня есть этот код. Я всегда генерирую исключение, но ВСЕГДА хочу, чтобы оно перешло к методу then () .

    call.xmlHttpReq = $.ajax({
        url : url,
        dataType : 'json',
        type : 'GET'
    }).always(function(processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {

       throw "something";

    }).then(function() {

        alert("i want to always run no matter what");
    });

Я пробовал использовать done () , complete () и еще один always () , но, похоже, ничего не работает.

Вот JSFiddle:

http://jsfiddle.net/qv3t3L0m/

Оливер Уоткинс
источник
просто добавьте его в always...
Дэвид Фреголи
1
Вы не можете поймать асинхронно генерируемые ошибки, это то, что вы ищете. Вам нужно будет самостоятельно оформить это в виде try-catch-finallyутверждения.
Берги
3
Он всегда переходит к функции always (), поэтому он так удачно назван.
adeneo
Если jQuery не обрабатывает каждую попытку / уловку в обратном вызове, throw "something";просто остановит выполнение кода.
plalx
@Bergi, я не знаком с jQuery promises impl, но если он совместим с Promises / A +, то возникшие ошибки будут переданы в errorHandler, переданный тогда. Итак, если он передаст вторую функцию затем, он получит «что-то» в качестве параметра.
Дэвид МакМаллин

Ответы:

130

См. Этот пример:

$.ajax({
        type: "GET",
        dataType: dataType,
        contentType: contentType,
        async: TRUE,
        url: $('html form:nth-child(1)').attr('action') + "?" $('html form:nth-child(1)').serialize(),
        success: function(data) {
            console.log("FUNFOU!");
        },
        error: function(data) {
            console.log("NÃO FUNFOU!");
        },
        complete: function(data) {
            console.log("SEMPRE FUNFA!"); 
            //A function to be called when the request finishes 
            // (after success and error callbacks are executed). 
        }
    });

Для получения дополнительной информации: http://api.jquery.com/jquery.ajax/

Рафаэль Гомес Франсиско
источник
27
.complete()устарело; использовать .always()сейчас. api.jquery.com/jQuery.ajax
mlg
4
Понравился глагол FUNFAR: D
Бруно Родригес
4
Параметр @mlg: complete не является устаревшим, они устарели только для обратного вызова .complete (), поскольку теперь объекты jqXHR реализуют интерфейс Promise. См. Ответ на этот вопрос: stackoverflow.com/questions/15821141/…
jeanie77 05
45

.always()должно сработать. См . Раздел «Объект jqXHR » на http://api.jquery.com/jQuery.ajax/ .

jqXHR.always (function (data | jqXHR, textStatus, jqXHR | errorThrown) {}); Метод .always () является альтернативой полной опции обратного вызова и заменяет устаревший метод .complete ().

В ответ на успешный запрос аргументы функции такие же, как и у .done (): data, textStatus и объекта jqXHR. Для неудавшихся запросов аргументы такие же, как у .fail (): объект jqXHR, textStatus и errorThrown. Обратитесь к deferred.always () за подробностями реализации.

См. Также http://api.jquery.com/deferred.always/

Jrummell
источник
11

Приведенные ниже предложения не будут работать в jQuery, потому что реализация обещания jQuery не обрабатывает ошибки, возникающие в методах, переданных ему. Я оставляю их здесь только в качестве иллюстрации того, что могло бы быть возможно, если бы jQuery был совместим с обещаниями / A +. Как справедливо указывает Берги, вам придется вручную заключить код в собственный блок try catch.

call.xmlHttpReq = $.ajax({
    url : url,
    dataType : 'json',
    type : 'GET'
}).then(function(processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {

   throw "something";

}).always(function() {

    alert("i want to always run no matter what");
});

Хотя я не уверен, что обещание jquery всегда поддерживает, альтернативой было бы использовать then (снова) и передать ту же функцию, что и successHandler, и errorHandler, например:

call.xmlHttpReq = $.ajax({
    url : url,
    dataType : 'json',
    type : 'GET'
}).then(function(processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {

   throw "something";

}).then(function() {

    alert("i want to always run no matter what");
},
function() {

    alert("i want to always run no matter what");
});
Дэвид Макмаллин
источник
jQuery thenне обнаруживает ошибок в обратном вызове. Ли вы попробовать это?
Берги
извините, я пробовал использовать then-> always и имел две функции в моем then, но у меня все еще та же проблема.
Оливер Уоткинс
Приношу искренние извинения, посмотрев отложенные документы jquery, я подумал, что это сработает, но я явно ошибался, и Берги справедливо указывает, что мне следовало проверить в песочнице.
Дэвид МакМаллин
3

Замечание для тех, кто использует jQuery 3.0 и новее

Уведомление об устаревании: обратные вызовы jqXHR.success (), jqXHR.error () и jqXHR.complete () удалены с jQuery 3.0. Вместо этого вы можете использовать jqXHR.done (), jqXHR.fail () и jqXHR.always ().

Как в официальной документации

Джаявардхан Ганге
источник
2

Есть ошибка, в которой ajax зависит от сервера, лучше всего проверять статус с "завершенным", типа "успех", "ошибка" и другие не являются 100% PUT, POST и GET ... посмотрите на примере

$.ajax({
    url: '/api/v2/tickets/123456.json',
    ....
    ....
    ....
    complete: function(data) { 
        if (data.statusText == "success") { 
            console.log("Sent successfully");
        } else { 
            console.log("Not Sent");
        }
    }
});

Извините, плохой английский! Ура ;-)

KingRider
источник
1

если вам нужно одно определение кода для всех запросов ajax, вы можете сделать это так

$(document).ajaxComplete(function () {
    console.log('ajax complete on doc');
})
sairfan
источник