DEV Community

Cristian Fernando
Cristian Fernando

Posted on • Updated on

ES6: Promesas en JavaScript

Índice

  1. Ejecución de código en Javascript
  2. ¿Qué es una operación asíncrona?
  3. ¿Qué es una promesa?
  4. Estados de una promesa
  5. Manipulación de promesas
  6. Creación de promesas
  7. Consumir promesas
  8. Encadenamiento de promesas
  9. Promesas paralelas vs Promesas en serie
  10. Ejemplos prácticos con promesas
  11. Referencias
  12. Conclusiones

1. Ejecución de código en Javascript

Javascript es un lenguaje de programación cuya ejecución de código se lo realiza de arriba hacia abajo y en orden consecutivo, en otras palabras, línea por línea. Por ejemplo:

const getNombre = (nombre) => {
  console.log(`Hola ${nombre}`);
}

getNombre("Carlos")
getNombre("Ana")
getNombre("Susana")
/*
"Hola Carlos"
"Hola Ana"
"Hola Susana"
*/
Enter fullscreen mode Exit fullscreen mode

Este pequeño código nos regresa por consola un saludo a Carlos, Ana y Susana en ese orden, por que así es como estamos llamando a las funciones. Este es el comportamiento por defecto de javascript.

2. ¿Qué es una operación asíncrona?

JavaScript es un lenguaje de un solo hilo, esto lo hace síncrono, osea, solo puede ejecutar una tarea a la vez.
Una operación es asíncrona cuando esta puede realizarse al mismo tiempo que otros eventos independiente al flujo principal de la aplicación.
El ejemplo más común de una operación asíncrona es la llamada a una API, está llamada demorará un tiempo x en devolver una respuesta a la aplicación y mientras esto suceda el sistema no debe paralizarse, debe continuar funcionando.

3. ¿Qué es una promesa?

Antes de lanzar la típica definición de una promesa que puedes encontrar en cualquier blog prefiero hacer una simple analogía para que se comprenda mejor.

¿Qué es una promesa en la vida real?

Imagina que estás leyendo Yo Robot del maestro de la ciencia ficción Isaac Asimov

img

Entonces dices algo como: "Prometo que acabaré de leer este libro en 1 semana"

Dicha promesa solo puede tener 2 conclusiones:

  • Pasada una semana efectivamente acabas de leer el libro, por tanto la promesa fue cumplida.
  • Durante toda esa semana tuviste muchos deberes y exámenes entonces no pudiste acabar de leer el libro, por ende, la promesa que hiciste no fue cumplida.

No hay otra opción, al cabo de una semana si o si sucederá lo uno o lo otro.

De la misma manera que las promesas funcionan en la vida real lo hacen en javascript, entonces podríamos definir una promesa como:

Una promesa es un objeto que representa una operación asíncrona que puede resolverse ahora, en un futuro o nunca

4. Estados de una promesa

En esencia una promesa puede tener 3 estados:

img

  • fulfill: significa que la promesa fue satisfecha o cumplida.
  • reject: quiere decir que la promesa no fue cumplida.
  • pending: es el estado inicial de una promesa, hasta que no se cumpla el tiempo estipulado de espera una promesa estará pendiente.

5. Manipulación de promesas

Cuando hablamos de promesas hay 2 maneras de usarlas o manipularlas en nuestro código:

  • Crear una promesa
  • Consumir una promesa

En la práctica casi nunca crearemos promesas, por lo general nos la pasaremos consumiendolas

6. Creación de promesas

Para crear una promesa debemos usar el objeto Promise de la siguiente manera:

const promise = new Promise ((resolve, reject) => {
  let isTrue = true;
  if(isTrue){
    setTimeout(() => {
      resolve("Promesa cumplida");
    },3000)
  }else{
    reject("Promesa rechazada");
  }
});

Enter fullscreen mode Exit fullscreen mode

Como puedes observar una promesa recibe 2 funciones como parámetros, resolve se ejecutará cuando la promesa se cumpla y reject cuando la promesa no se cumpla.
En nuestro caso si la variable let isTrue = true entonces se llamará a resolve, caso contrario se llamaría a reject.

Ahora, ¿cómo podemos usar esta promesa? Debemos aprender a consumirla.

7. Consumir promesas

Para consumir una promesa debemos tener bien en cuenta que las promesas tienen 3 métodos indispensables para su consumo:

  • then() se encarga de evaluar el caso cuando la promesa se cumpla.
  • catch() atrapa los errores en caso de que la promesa falle.
  • finally() se ejecuta siempre, independientemente si la promesa se cumplió o no.

Para consumir la promesa del ejemplo pasado, podríamos hacer lo siguiente:

promise
  .then((mensaje) => console.log(mensaje))
  .catch((error) => console.log(error))
Enter fullscreen mode Exit fullscreen mode

Como la promesa se cumple, entonces se ejecuta el método .then() e imprime en la consola "Promesa cumplida" después de 3 segundos.

El ejemplo completo se vería de la siguiente manera:

const promise = new Promise ((resolve, reject) => {
  let isTrue = true;
  if(isTrue){
    setTimeout(() => {
      resolve("Promesa cumplida");
    },3000)
  }else{
    reject("Promesa rechazada");
  }
});

promise
  .then((mensaje) => console.log(mensaje))
  .catch((error) => console.log(error))

// "Promesa cumplida" (este mensaje se verá después de 3 seg)
Enter fullscreen mode Exit fullscreen mode

8. Encadenamiento de promesas

En la práctica la mayoría de las promesas se encadenan, esto resulta muy útil y además es muy sencillo hacerlo. Solo debemos usar un then() después del otro y asegurarnos de escribir un return entre ellos. Por ejemplo:

Cuando encadenamos promesas es importante usar siempre un return

9. Promesas paralelas vs Promesas en serie

Promesas en serie

¿No te ha pasado que en algún examen o prueba se te presentaron preguntas que dependen una de la otra?
Por ejemplo en un examen de 10 preguntas, para poder responder la pregunta 5 necesitas si o si la respuesta de la pregunta 4.
Ahora imagina que te toma 10 minutos resolver la pregunta 4 y 5 minutos resolver la pregunta 5; en total pudiste responder ambas en 15 minutos.

Este es un claro ejemplo de una serie, donde para poder empezar x necesitas terminar y.

Sigamos con la analogía, continuamos con nuestro examen la pregunta 7 nos toma 3 minutos y la pregunta 8 nos toma 5 minutos, ambas preguntas no son dependientes, ahora, al no depender una de la otra no sería genial poder de alguna manera responder ambas preguntas al mismo tiempo, por ejemplo, tener la habilidad de tomar un lápiz con cada mano y responder ambas preguntas al mismo tiempo, ¿cuanto tardarias en responder ambas? Si dijiste 5 minutos dejame decirte que entendiste el ejemplo a la perfección.

Al igual que las preguntas de un examen, puede haber promesas en paralelo y promesas en serie; saber diferenciar entre ambas puede significar un ahorro de tiempo importante en la respuesta de la operación asíncrona y por ende un sistema más óptimo.

Ahora veamos un ejemplo de promesas en serie

Es este ejemplo asumimos que para poder responder una pregunta primero debemos responder su antecesora, todas las preguntas son dependientes, por ende empleamos encadenamiento de promesas

Promesas en paralelo

Para poder resolver problemas en paralelo podemos usar Promise.all() y pasarle un arreglo con todas nuestras promesas a evaluar. De esta manera todas las promesas se ejecutarán al mismo tiempo, veamos:

Como puedes ver ahora el tiempo de espera se reduce considerablemente puesto que en este ejemplo las promesas no dependen unas de otras.

10. Ejemplos prácticos con promesas

Ahora veremos un poco más de las promesas resolviendo algunos ejercicios:

  • Realizar una función que genere un número random entre 0 y 10, cuando el número sea menor o igual 5 la promesa debe ser resuelta, caso contrario debe ser rechazada. Independientemente del resultado de la promesa mostrar el mensaje "Promesa acabada" para indicar que el proceso terminó

  • Realizar una llamada tipo get a la API de json placeholder usando promesas

11. Referencias


12. Conclusiones

  • El código en javascript se ejecuta secuencialmente, línea por línea de arriba hacia abajo.
  • Una operación asíncrona rompe con el flujo normal del código, por ejemplo la llamada a una API.
  • Una promesa es un objeto que representa una operación asíncrona que puede resolverse ahora, en un futuro o nunca
  • Una promesa tiene 3 estados: fulfill, reject, pending.
  • Una promesa tiene 3 métodos básicos: then(), catch(), finally()
  • resolve se usa cuando una promesa se resuelve.
  • reject cuando la promesa termina con errores.
  • Se puede manipular promesas de 2 maneras: creandolas y consumiendolas.
  • El encadenamiento de promesas es normal y bastante usado.
  • Las promesas en serie se resuelven una detrás de la otra, tardan más tiempo en concluir.
  • Las promesas en paralelo usan el método all() para que se resuelvan todas al mismo tiempo, super útiles para optimizar acciones síncronas.

Discussion (4)

Collapse
echofly profile image
echofly

English please!!!

Collapse
duxtech profile image
Cristian Fernando Author

Por ahora todos mis post son en español, mi ingles esta muy oxidado; espero en un futuro no muy lejano poder escribir post de estos temas 100% en ingles. Saludos.

Collapse
bygossipgirl profile image
Beatriz

Gracias por el post ha sido muy enriquecedor. 👏👏

Collapse
duxtech profile image
Cristian Fernando Author

Gracias a ti por tu comentario 😎