$.Deferred() de jQuery
Contenido
$.Deferred. ¿Qué es?
El objeto deferred se introdujo en jQuery a partir de la versión 1.5 y provocó una importante mejora en las interfaces de programación asíncrona que se usaban hasta entonces. Es un objeto concatenable sobre el que se pueden registrar múltiples callbacks que se ejecutarán en función del resultado final de la deferred.
A partir de la versíón 1.5 las llamadas ajax de jquery $.ajax(), $.get(), $.getJSON(), $.post(), …etc. devuelven un objeto promise que no es otra cosa que una interfaz de sólo lectura del objeto deferred.
3 estados de $.Deferred
- pending: El objeto está en un estado incompleto
- resolved: El objeto se ha resuelto
- rejected: el objeto se ha rechazado
Cuando lo creamos, por supuesto, estará “pending”. Si llamados al método resolve() del objeto deferred lo pasaremos al estado “resolved”. Por el contrario, si llamamos al método reject() lo pasaremos al estado “rejected”.
A través de los métodos deferred.done, deferred.fail y deferred.always es posible desacoplar las funciones de devolución de la misma petición Ajax, permitiendo un manejo más cómodo de las mismas.
Además, puedo adjuntarle una serie de callbacks que se ejecutarán en función del estado al que lo esté pasando:
- .then()
- .done()
- .fail()
Método $.when
Permite sincronizar la resolución o rechazo de varias deferred.
Lo que hace este código es ejecutar las tres peticiones ajax y cuando se resuelvan los deferreds de cada petición, si todos están “resolved” ejecutará el callback de done() y si alguno se rechaza el de fail().
$.when($.get("url1"), $.get("url2"), $.get("url3")) .done(function() { alert("Todo bien!!"); }) .fail(function() { alert("Todo mal!!"); }); |
Retornando promises
Las llamadas ajax de jquery retornaban objetos promise en lugar de deferreds y que estos eran interfaces de sólo lectura de un objeto deferred. El objetivo no es otro que “capar” la manipulación en el exterior del objeto deferred.
function wait() { var deferred = $.Deferred(); setTimeout(function() { deferred.resolve(); }, 5000); return deferred.promise(); } wait().done(function() { alert("He esperado 5 segundos!!"); }); |
Colas de funciones de devolución en petición ajax
Es posible crear colas de funciones de devolución o atarlas a diferentes lógicas/acciones:
var ajax = $.ajax({ url : 'index.php' }); // primera función de devolución a ejecutar ajax.then(function(){ alert('Primera función de devolución en caso satisfactorio'); }); // segunda función de devolución a ejecutar // inmediatamente después de la primera ajax.done(function(){ alert('Segunda función de devolución en caso satisfactorio'); }); // si el usuario hace click en #element se // agrega una tercera función de devolución $('#element').click(function(){ ajax.done(function(){ alert('Tercera función de devolución si el usuario hace click'); }); }); |
Gráfico de estados y manejadores
Bibliografía
- http://yagoperez.com/jugando-con-jquery-deferred/
- http://api.jquery.com/category/deferred-object/
- https://www.arkaitzgarro.com/jquery/capitulo-12.html