La cosa va de promesas

Cuando se nos habla de promesas se quiere hacer referencia a algo que no ha pasado todavía y que puede llegar a ocurrir en un futuro. En la programación asíncrona también existe algo parecido con el mismo nombre “promise“, y representa un dato o un valor no conocido pero que en algún momento puede llegar a estar.

Para entendernos mejor, supongamos que queremos concatenar (unir) el contenido de dos webs diferentes, la manera más simple que nos viene a la cabeza sería:

[code language=”javascript”]
function descargarWeb(web){
//descargar el contenido
return contenido;
}
var web1 = descargarWeb(“web1”),
web2 = descargarWeb(“web2”),
contenido = web1+web2;
[/code]

Al hacerlo de esta manera ocurrirá que, a no ser que tengas una línea de Internet como la de la NASA, cuando se ejecute la suma (web1+web2) pueden no haberse cargado todavía los contenidos de las dos páginas, por lo que no obtendríamos el resultado esperado. Que las cosas funcionen a ratos no vale, así que habrá que mejorarlo, ¿pero cómo? Pues mediante el uso de una función que será utilizada como callback y que comprobará que hemos obtenido el contenido de las dos webs antes de concatenarlas. Algo así:

[code language=”javascript”]
var web1,web2,contenido;
function descargarWeb(web, callback){
//Descargar el contenido
callback();
}
function comprobarYConcatenar(){
if(web1 && web2)
contenido = web1+web2;
}
descargarWeb (“web1”, comprobarYConcatenar);
descargarWeb (“web2”, comprobarYConcatenar);
[/code]

A partir de aquí ya tenemos nuestro problema solucionado ya que siempre se realizará la suma cuando se hayan cargado los datos de ambas webs, pero como no es una solución muy elegante vamos a ver el mismo ejemplo utilizando las promesas de jQuery. Una promesa se caracteriza por su estado, el cual siempre se inicia en un punto de espera (pending), para posteriormente pasar a uno de los dos siguientes estados:

  • Rejected. Si se ha producido algún error.
  • Resolved. Si se ha obtenido el valor con éxito.

Ahora que entendemos qué es una promesa, necesitamos saber cuándo cambia de estado. Como toda promesa proviene de un objeto deferred (lo podemos definir como un trabajo no finalizado) disponemos de varias funciones (handlers) que nos permiten ejecutar nuestro código a medida que va cambiando el estado, estas funciones son:

  • $.when(promise/s). Recibe como parámetros una o varias promesas.
  • deferred.then(callback/s). Recibe como parámetros una o varias funciones que se ejecutarán siempre que el estado de la promesa cambie, no importa a cuál.

promises
Este es el mismo ejemplo, pero bien hecho:

[code language=”javascript”]
var contenido,
def1=$.deferred(),
def2=$.deferred(),
web1=def1.promise(),
web2=def2.promise();
function descargarWeb1(){
//obtener el contenido
web1.data=contenidoDescargado;
def1.resolve();
}
function descargarWeb2(){
//obtener el contenido
web2.data=contenidoDescargado;
def2.resolve();
}
$.when(web1,web2).then(function(){
contenido=web1.data+web2.data;
});
descargarWeb1();
descargarWeb2();
[/code]

Analicemos el código:
Lo primero de todo consiste en instanciar las dos promesas que almacenarán el contenido de las webs, para ello utilizamos la función $.Deferred de jQuery. Lo siguiente será crear la función y asociarla, mediante los handlers, al cambio de estado de ambas promesas, y por último solo queda descargar el contenido y esperar a que termine.

Esto es algo muy simple comparado con lo que se puede llegar a hacer, a partir de aquí solo hay que echarle imaginación…

Deja un comentario