¿Hay algún análogo a un 'finalmente' en las llamadas jQuery AJAX?

84

¿Existe un análogo de Java 'finalmente' en las llamadas jQuery AJAX? Tengo este código aquí. En mi siempre arrojo una excepción, sin embargo SIEMPRE quiero que vaya al método 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");
    });

He intentado usar done () , complete () y el otro always () , pero nada parece funcionar.

Aquí está JSFiddle:

http://jsfiddle.net/qv3t3L0m/

Oliver Watkins
fuente
simplemente añádalo a always...
David Fregoli
1
No puede detectar errores lanzados de forma asincrónica, eso es lo que está buscando. Deberá envolverlo en una try-catch-finallydeclaración usted mismo.
Bergi
3
Que siempre va a la función siempre (), es por eso que está tan bien llamado.
adeneo
A menos que jQuery maneje cada intento / captura en una devolución de llamada, throw "something";simplemente detendrá la ejecución del código.
plalx
@Bergi, no estoy familiarizado con las promesas implícitas de jQuery, pero si cumple con Promises / A +, los errores arrojados se pasarán a un errorHandler que se le haya pasado. Entonces, si le pasa una segunda función, recibirá "algo" como parámetro.
David McMullin

Respuestas:

130

Vea este ejemplo:

$.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). 
        }
    });

Para más información: http://api.jquery.com/jquery.ajax/

Rafael Gomes Francisco
fuente
27
.complete()ha sido desaprobado; usar .always()ahora. api.jquery.com/jQuery.ajax
mlg
4
Le gustó el verbo FUNFAR: D
Bruno Rodrigues
4
@mlg: el parámetro completo no está en desuso, solo han desaprobado la devolución de llamada .complete (), ya que ahora los objetos jqXHR implementan la interfaz Promise. Consulte la respuesta a esta pregunta: stackoverflow.com/questions/15821141/…
jeanie77
45

.always()Deberia trabajar. Consulte la sección El objeto jqXHR en http://api.jquery.com/jQuery.ajax/ .

jqXHR.always (función (datos | jqXHR, textStatus, jqXHR | errorThrown) {}); Una construcción alternativa a la opción de devolución de llamada completa, el método .always () reemplaza el método obsoleto .complete ().

En respuesta a una solicitud exitosa, los argumentos de la función son los mismos que los de .done (): data, textStatus y el objeto jqXHR. Para solicitudes fallidas, los argumentos son los mismos que los de .fail (): el objeto jqXHR, textStatus y errorThrown. Consulte deferred.always () para obtener detalles de implementación.

Consulte también http://api.jquery.com/deferred.always/

jrummell
fuente
11

Las siguientes sugerencias no funcionarán en jQuery, porque la implementación de la promesa de jQuery no maneja los errores lanzados en los métodos pasados ​​a ese entonces. Solo los dejo aquí como una ilustración de lo que podría ser posible si jQuery cumpliera con promises / A +. Como bien señala Bergi, tendrá que ajustar manualmente su código en su propio bloque 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");
});

Aunque no estoy seguro de si la promesa de jquery es compatible siempre, una alternativa sería usar then (nuevamente) y pasar la misma función como successHandler y errorHandler, así:

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");
});
David McMullin
fuente
jQuery's thenno detecta errores en la devolución de llamada. ¿Sabía usted intenta esto?
Bergi
lo siento, intenté usar entonces-> siempre, y tener dos funciones en mi entonces, pero todavía tengo el mismo problema.
Oliver Watkins
más sinceras disculpas, después de mirar los documentos diferidos de jquery pensé que esto funcionaría, pero estaba claramente equivocado y Bergi señala con razón que debería haber verificado en una caja de arena.
David McMullin
3

Solo una nota para aquellos que usan jQuery 3.0 y posterior

Aviso de obsolescencia: las devoluciones de llamada jqXHR.success (), jqXHR.error () y jqXHR.complete () se eliminan a partir de jQuery 3.0. Puede utilizar jqXHR.done (), jqXHR.fail () y jqXHR.always () en su lugar.

Como en la documentación oficial

Jayavardhan Gange
fuente
2

Hay un error ajax que depende del servidor, es necesario comprobar el estado con "completo" es el mejor, una especie de "éxito", "error" y otros no son 100% de los PUT, POST y GET ... mira en un ejemplo

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

¡Lo siento mal inglés! Anímate ;-)

KingRider
fuente
1

si desea una definición de código para todas las solicitudes ajax, puede hacerlo así

$(document).ajaxComplete(function () {
    console.log('ajax complete on doc');
})
sairfan
fuente