Although success
has been the traditional way to successfully call back in jQuery, however, since the implementation of $.Deferreds
and callbacks
more sophisticated, done
is the preferred way to implement callbacks from success.
In the jQuery documentation we read the following:
Disabling notice : Callbacks jqXHR.success
()
, jqXHR.error ()
and jqXHR.complete ()
are removed from
jQuery 3.0 You can use jqXHR.done ()
, jqXHR.fail ()
and
jqXHR.always ()
instead.
This means that from jQuery 3 it is recommended to use done
.
Why use done
?
Because the jqXHR objects returned by $ .ajax ()
from jQuery 1.5 implement the Promise interface, giving them all the properties, methods and behavior of a Promise (see object Deferred for more information). These methods take one or more function arguments that are called when the $ .ajax ()
request ends. This allows you to assign multiple callbacks in a single request and even assign callbacks after the request has been completed. (If the request is already complete, the callback will trigger immediately.)
The available Promise methods of the jqXHR object include:
-
jqXHR.done(function( data, textStatus, jqXHR ) {});
An alternative construction to the successful callback option, see deferred.done ()
for implementation details.
-
jqXHR.fail(function( jqXHR, textStatus, errorThrown ) {});
An alternative construction to the error callback option, the .fail ()
method replaces the obsolete .error () method. See deferred.fail ()
for details on the implementation.
-
jqXHR.always(function( data|jqXHR, textStatus, jqXHR|errorThrown ) { });
(added in jQuery 1.6)
An alternative construction to the full callback option, the .always ()
method replaces the obsolete .complete ()
method.
In response to a successful request, the arguments of the function are the same as those of .done ()
: data, textStatus, and object jqXHR. For failed requests, the arguments are the same as those in .fail ()
: the jqXHR object, textStatus, and errorThrown. See deferred.always () for details on the implementation.
-
jqXHR.then(function( data, textStatus, jqXHR ) {}, function( jqXHR, textStatus, errorThrown ) {});
It incorporates the functionality of the .done ()
and .fail ()
methods, allowing (as of jQuery 1.8) that the underlying Promise be manipulated. See deferred.then ()
for details on the implementation.
The good thing about done
is that the return value of $.ajax
is now a deferred promise that may be linked to any other place in your application. So let's say you want to make this ajax call from a few different places. Instead of passing your success function as an option to the function that makes this ajax call, you can only have the return function $.ajax
and link your callbacks with done
, fail
, then
, or whatever is. Keep in mind that it is always a callback that will be executed if the request succeeds or fails. done
will only be activated when the ajax request is successful.
Complete example using the above:
// Se asignan manejadores inmediatamente después de hacer la petición
// y se recuerda el objeto jqXHR para esta petición
var jqxhr = $.ajax( "example.php" )
.done(function() {
alert( "èxito" );
})
.fail(function() {
alert( "error" );
})
.always(function() {
alert( "completado" );
});
// Hacer otra cosa aquí ...
// Asignar otra función de completado para la petición de más arriba
jqxhr.always(function() {
alert( "completado segundo" );
});
Another example:
function xhr_get(url) {
return $.ajax({
url: url,
type: 'get',
dataType: 'json',
beforeSend: mostrarImagenCargando
})
.always(function() {
// Por ejemplo removemos la imagen "cargando..."
})
.fail(function() {
// Manejar errores
});
}
xhr_get('/index').done(function(data) {
// Hacer algo con data
});
xhr_get('/id').done(function(data) {
// hacer algo con el id de data
});
An important benefit of this in terms of maintenance is that it has wrapped its ajax mechanism in a specific function of the application. If you decide that you need your $.ajax
call to operate differently in the future, or use a different ajax method, or get away from jQuery, you just have to change the xhr_get
definition (be sure to return a promise or at least one method done
, in the case of the previous example). All other references throughout the application can remain the same.
There are many more things (much cooler) that you can do with $.Deferred,
one of which is to use pipe
(or better then
) to trigger an error in an error reported by the server, even when the request $.ajax
succeeds.
For example:
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) {
// No funcionará si el json retornado desde ajax no tiene el código de respuesta 200
});
Sources: