Share on FacebookTweet about this on TwitterShare on Google+

Ajax y jQuery

Cuando trabajamos con JavaScript y jQuery es habitual manejar eventos asíncronos mediante peticiones AJAX. Si queremos realizar algo una vez que la llamada asíncrona termine, debemos utilizar una función de callback.
Ejemplo: Una vez se ejecute el script de servidor ejecutaremos una función anónima que muestre un texto por consola:

Como la llamada AJAX es asíncrona, el “Hola Mundo” aparecerá en consola antes que la respuesta del servidor: JavaSript continua su ejecución aunque la llamada asíncrona no haya terminado.
jQuery también permite elaborar múltiples callbacks y asociarlos a una función incluso aunque ésta haya sido completada:

El problema principal es que podemos querer varias funciones de callback o incluso varias llamadas asíncronas que se concatenen y se ejecuten en función del resultado de la anterior. Siguiendo los ejemplos de código que hemos visto, implementar esto con jQuery no sería complejo pero nos haría tener un código poco legible, tipo spaghetti.

Las promises están desde final de 2013 de forma nativa en JavaScript. Sin embargo no están implementadas en todos los navegadores y hace falta utilizar polyfills.

Estructuras mediante promesas

jQuery ha tenido críticas sobre su uso en arquitecturas grandes frente a otras librerías como YUI. Desde la versión 1.5 se reescribió el módulo de AJAX y se implementó el nuevo objeto Deferred.
El objeto Deferred representa un trabajo por realizar y la promesa es un objeto que representa un valor que todavía se desconoce. Todo objeto Deferred tiene un objeto de tipo Promise donde se guardará el resultado de la operación.
promises
La ventaja que tiene utilizar el objeto Deferred respecto a la programación AJAX con jQuery tradicional es que desacopla las llamadas asíncronas de sus dependencias (funciones de callback), de modo que queda el código más legible volviendolo además más potente como veremos ahora.
Veamos las tres estructuras que podemos realizar, que se podrían combinar para realizar tareas más complejas.

Pila

La llamada $.ajax devuelve un objeto de tipo Promise de jQuery. Desde dos sitios diferentes del código podríamos realizar algo en el momento que la promesa se resolviera:

Tareas en paralelo

Se ejecutan las tareas 1 y 2 de forma asíncrona. Mediante el método $.when recogeremos la finalización de ambas promesas:

Tareas secuenciales

Ejecutamos varias tareas de modo que cuando acabe una comience la otra, mediante el método $.then(). Este método devuelve a su vez una promesa por lo que se puede utilizar sobre el un done(), fail()…

deferred vs promise

¿Cuál es la diferencia entre un objeto de tipo deferred y un objeto de tipo promise? Como hemos visto en los ejemplos anteriores, un objeto de tipo promise es lo que se devuelve en funciones asíncronas. Necesitaremos un objeto de tipo deferred cuando escribamos dicha función nosotros mismos.
Un objeto deferred es similar a un objeto promise pero además tiene dos métodos resolve() y reject() que dispararán las funciones asignadas mediante done() o fail(). Si le damos parámetros al resolve() o al reject() los pasarán respectivamente a las funciones asignadas en el done() o fail().
Veamos un ejemplo, lo puedes ver también en un jsfiddle:

Comments

  1. Javi

    Muchas gracias. Sólo con tu ejemplo claro, escueto y preciso he entendido correctamente los deferreds y promises.

Leave a Reply

Your email address will not be published. Required fields are marked *