Las «Promesas» y «Cadenas de Promesas» de Javascript explicadas en inglés

He estado muy entusiasmado con las Promesas desde que fueron introducidas hace un año. Aunque hay muchos posts y opiniones flotando por ahí, las Promesas no harán que tu código sea más performante… lo harán más fácil de leer y entender (lo que en mi libro, a menudo cuenta mucho más!)

Para la primera parte de este post, voy a explicar la estructura básica de las promesas. Si tienes eso cubierto, siéntete libre de pasar a la segunda mitad del post.

Las promesas explicadas en inglés

Aquí está la estructura básica de una promesa en Javascript:

Un típico (y escurridizo) fragmento de código. Voy a intentar desglosar lo que ocurre.

Para empezar, céntrate sólo en las líneas 1-15:

  • Aquí está la instanciación. Esta línea básicamente crea una promesa. Una promesa en JS necesita algo que hacer, una tarea. Así que la función que ves que se pasa aquí – function (resolve,reject) {…} es esa tarea
  • A continuación ves el cuerpo de la tarea. Puedes hacer cosas aquí. En algún lugar de este bloque de código, tienes que decidir si las cosas han ido bien o no. Por ejemplo, si estabas usando este espacio para obtener una imagen, o la recibiste (fue bien)… o no (no tan bien).
  • Si las cosas fueron bien, llamarás a alguna función que marcará esta promesa como «resuelta». Si las cosas no fueron según lo previsto, «rechazará» esta promesa. (hablaremos de esto con más detalle en un segundo)

Ahora centrémonos en la parte restante del fragmento de código, las líneas 17-27:

  • Hasta ahora, en las líneas 1-15, sólo has definido tu objeto Promise
  • En las líneas 17 & 22, básicamente le adjuntas un handler
  • promise.XXXX (donde XXX podría ser «.then» o «.catch», etc.) básicamente ejecuta la función definida en la promesa (líneas 1-15). Basándose en cómo fueron las cosas (resueltas o rechazadas) llamarán a las funciones en «.then» y «.catch» respectivamente. Así que si tu promesa se resolvió (…las cosas fueron bien), se ejecutará la función dentro de .then(…), de lo contrario se ejecutará la función en .catch(…).

NOTA:

  • «.then(function)» devuelve una Promesa. Además, sólo se puede llamar a «.then(…)» o «.catch(…)» sobre objetos Promise.

Ahora que hemos cubierto lo básico, veamos un ejemplo más interesante de lo que podemos hacer con Promises.

Cadenar Promesas para realizar múltiples peticiones

Problema: Recientemente, me encontré con una situación en la que en necesitaba obtener un montón de URLs una tras otra. Sin embargo, la respuesta para cada URL tuvo que ser manejado de manera diferente en función de la URL.

Para el bien de este post, vamos a suponer que las urls que se obtiene son:

  • google.com
  • apple.com
  • amazon.com

Aquí tienes una versión simplificada del script que utilicé para manejar esto:

Desglosemos esto:

  • Líneas 1-11: Crea una simple envoltura alrededor del método AJAX Get proporcionado por jQuery. Esto simplemente pasará la respuesta a la devolución de llamada especificada.
  • Líneas 18-51: A continuación, creo tres funciones (¡sí! ¡Funciones!) que devuelven una promesa JS
  • Cada promesa internamente hace esto – utiliza la envoltura Ajax para obtener su url, y una vez que se reciben los datos/respuesta, hace algo con los datos y finalmente llama a «resolver()»
  • En la línea 54: Encadeno estas promesas una tras otra. Nótese, que cada una de estas funciones devuelve una promesa (y no es una Promise en sí misma). Por eso uso «first()».then(…) en lugar de «first.then(…)»

Para aclarar más, aquí hay una forma de ver la cadena de promesas.

La cadena de promesas – codificada por colores con corchetes

De esta manera, puedes obtener secuencialmente cada URL, manejarla como desees y disparar la función «resolved()» para desencadenar la siguiente Promise en la cadena 🙂

Nota: si intentas ejecutar el fragmento de código anterior en el navegador, necesitarás habilitar CORS. Aquí hay una extensión de Chrome que puede ayudar a hacer esto con un simple clic.

Espero que hayas disfrutado de este post.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.