2012-01-12 13 views
264

He estado trabajando con jQuery y AJAX durante algunas semanas y vi dos formas diferentes de 'continuar' la secuencia de comandos una vez que se realizó la llamada: success: y .done.jQuery.ajax handling continue responses: "success:" versus ".done"?

De la sinopsis de la jQuery documentation obtenemos:

.done(): Descripción y agregar controladores que se llamará cuando se resuelve el objeto diferido.

success: (opción .ajax()): una función que debe invocarse si la solicitud tiene éxito.

Entonces, ambos hacen algo después de que se haya completado/resuelto la llamada AJAX. ¿Puedo usar uno u otro al azar? ¿Cuál es la diferencia y cuándo se usa uno en lugar del otro?

Respuesta

399

success ha sido el nombre tradicional de la devolución de llamada correcta en jQuery, definida como una opción en la llamada ajax. Sin embargo, desde la implementación de $.Deferreds y de devoluciones de llamada más sofisticadas, done es la forma preferida de implementar devoluciones de llamadas exitosas, ya que se puede invocar en cualquier deferred.

Por ejemplo, el éxito:

$.ajax({ 
    url: '/', 
    success: function(data) {} 
}); 

Por ejemplo, hecho:

$.ajax({url: '/'}).done(function(data) {}); 

Lo bueno de done es que el valor de retorno de $.ajax es ahora una promesa diferida que puede ser obligado a en cualquier otro lugar de tu aplicación. Entonces digamos que quieres hacer esta llamada ajax desde algunos lugares diferentes. En lugar de pasar su función de éxito como una opción a la función que realiza esta llamada ajax, puede hacer que la función devuelva $.ajax y enlazar sus devoluciones de llamada con done, fail, then, o lo que sea. Tenga en cuenta que always es una devolución de llamada que se ejecutará tanto si la solicitud tiene éxito como si falla. done solo se activará en caso de éxito.

Por ejemplo:

function xhr_get(url) { 

    return $.ajax({ 
    url: url, 
    type: 'get', 
    dataType: 'json', 
    beforeSend: showLoadingImgFn 
    }) 
    .always(function() { 
    // remove loading image maybe 
    }) 
    .fail(function() { 
    // handle request failures 
    }); 

} 

xhr_get('/index').done(function(data) { 
    // do stuff with index data 
}); 

xhr_get('/id').done(function(data) { 
    // do stuff with id data 
}); 

Un beneficio importante de esto en términos de capacidad de mantenimiento es que se ha envuelto su mecanismo de Ajax en una función específica de la aplicación. Si decide que necesita su llamada $.ajax para operar de manera diferente en el futuro, o usa un método ajax diferente, o se aleja de jQuery, solo tiene que cambiar la definición xhr_get (asegúrese de devolver una promesa o al menos un done método, en el caso del ejemplo anterior). Todas las otras referencias en toda la aplicación pueden permanecer igual.

Hay muchas cosas más (mucho más frío) que puede hacer con $.Deferred, una de ellas es utilizar pipe para provocar un fallo en un error reportado por el servidor, incluso cuando la solicitud $.ajax sí tiene éxito.Por ejemplo:

function xhr_get(url) { 

    return $.ajax({ 
    url: url, 
    type: 'get', 
    dataType: 'json' 
    }) 
    .pipe(function(data) { 
    return data.responseCode != 200 ? 
     $.Deferred().reject(data) : 
     data; 
    }) 
    .fail(function(data) { 
    if (data.responseCode) 
     console.log(data.responseCode); 
    }); 
} 

xhr_get('/index').done(function(data) { 
    // will not run if json returned from ajax has responseCode other than 200 
}); 

Leer más sobre $.Deferred aquí: http://api.jquery.com/category/deferred-object/

NOTA: A partir de jQuery 1.8, pipe está en desuso en favor del uso then exactamente de la misma manera.

+2

Me pregunto cómo se definen las interacciones de 'success:' /'.done() ', en todo caso. P.ej. ¿'success:' acaba de implementarse como el primer '.done()' en estos días? –

+5

¿Quieres decir si tienes 'success:' y '.done' en una llamada ajax? Buena pregunta. Como todas las otras devoluciones de llamada se llaman en el orden en que están vinculadas, mi suposición es sí, 'éxito 'simplemente se llama primero. – glortho

+1

Sí, ese parece ser el caso: http://jsfiddle.net/9L7dD/ – Adam

2

Si necesita async: false en su ajax, debe usar success en lugar de .done. De lo contrario, es mejor usar .done. Esto es de jQuery official site:

Como de jQuery 1.8, el uso de async: false con jqXHR ($ .Deferred) está en desuso; se debe utilizar los/error/completas opciones de devolución de llamadade éxito en lugar de los métodos correspondientes del objeto jqXHR como jqXHR.done().