Promesas en JavaScript

Las promesas en JavaScript son una herramienta esencial para manejar operaciones asíncronas de manera más controlada y predecible. Las promesas representan la eventual finalización o falla de una operación que se ejecuta en el futuro, permitiendo escribir código más limpio y fácil de mantener.

En este artículo exploraremos qué son las promesas, qué problemas resuelven y cómo funcionan, proporcionando ejemplos prácticos para comprender mejor su uso.

¿Qué es una Promesa en JavaScript?

Una promesa es un objeto en JavaScript que representa un valor que puede estar disponible en el presente, en el futuro o nunca. Estas se introdujeron para simplificar el manejo de la programación asíncrona, proporcionando una alternativa más estructurada que el uso de callbacks anidados.

const promesa = new Promise((resolve, reject) => {
  // contiene una operación
  // ...

  // devuelve el estado
  if (success) {
    resolve(value);
  } else {
    reject(error);
  }
});

Estados de una Promesa

Una promesa en JavaScript puede estar en uno de los siguientes tres estados:

  1. Pendiente (pending): La operación asíncrona aún no ha finalizado.
  2. Resuelta (fulfilled): La operación se completó con éxito y la promesa tiene un valor resultante.
  3. Rechazada (rejected): La operación falló y la promesa tiene un motivo de falla.

El estado de una promesa cambia de pending a fulfilled o rejected cuando la operación asíncrona termina y no puede cambiar de nuevo.


¿Qué Problemas Resuelven las Promesas?

Antes de que las promesas fueran introducidas en ES6, la forma principal de manejar la programación asíncrona en JavaScript era mediante callbacks. Aunque los callbacks funcionan, tienen algunas desventajas importantes:

  • Callback Hell: Cuando se anidan múltiples callbacks, el código se vuelve difícil de leer y mantener.
  • Manejo de Errores Complejo: La gestión de errores en callbacks anidados puede ser complicada.
  • Invocación de Callbacks Múltiples: Puede haber errores si un callback se llama varias veces, lo cual es difícil de controlar.

Las promesas resuelven estos problemas al proporcionar una estructura más limpia para manejar las operaciones asíncronas, con un enfoque basado en métodos para manejar el resultado o el error.


Creación de una Promesa en JavaScript

Para crear una promesa en JavaScript, se utiliza el constructor Promise, que toma una función ejecutora como argumento. Esta función ejecutora recibe dos parámetros: resolve y reject, que se utilizan para resolver o rechazar la promesa.

Ejemplo Básico de Creación de una Promesa

const promesa = new Promise((resolve, reject) => {
  const exito = true;
  
  if (exito) {
    resolve("La operación fue exitosa");
  } else {
    reject("Ocurrió un error en la operación");
  }
});

En este ejemplo la promesa se resuelve con resolve si la operación tiene éxito o con reject si ocurre un error.

Qué Hacen resolve y reject

  • resolve(valor): Cambia el estado de la promesa a fulfilled y envía el valor resultante.
  • reject(error): Cambia el estado de la promesa a rejected y envía un motivo de falla.

Manejo del Resultado de una Promesa

Una vez creada una promesa se pueden utilizar los métodos then y catch para manejar los resultados de la promesa.

Manejar la Promesa Resuelta: then()

El método then() se utiliza para manejar el valor de una promesa resuelta. Recibe una función que se ejecuta cuando la promesa cambia a fulfilled.

promesa.then(resultado => {
  console.log("Resultado:", resultado);  // Output: Resultado: La operación fue exitosa
});

Manejar la Promesa Rechazada: catch()

El método catch() se utiliza para manejar errores en la promesa. Recibe una función que se ejecuta cuando la promesa es rechazada.

promesa.catch(error => {
  console.log("Error:", error);
});

Ejecutar Código Independientemente del Resultado: finally()

El método finally() se ejecuta una vez que la promesa ha sido resuelta o rechazada, sin importar el resultado. Es útil para liberar recursos o realizar acciones finales.

promesa
  .then(resultado => console.log("Resultado:", resultado))
  .catch(error => console.log("Error:", error))
  .finally(() => console.log("Operación finalizada"));

Encadenamiento de Promesas

Una de las características más poderosas de las promesas es la posibilidad de encadenar múltiples operaciones asíncronas. Cada then() devuelve una nueva promesa, lo que permite encadenar las operaciones secuencialmente.

Ejemplo de Encadenamiento:

const promesaEncadenada = new Promise((resolve, reject) => {
    setTimeout(() => resolve(10), 1000);
});

promesaEncadenada
  .then(resultado => {
    console.log(resultado);  // Output: 10
    return resultado * 2;
  })
  .then(nuevoResultado => {
    console.log(nuevoResultado);  // Output: 20
    return nuevoResultado + 5;
  })
  .then(final => {
    console.log(final);  // Output: 25
  })
  .catch(error => console.log("Error:", error));

El encadenamiento de promesas ayuda a evitar la anidación excesiva y facilita la lectura del código.


Promesas vs. Callbacks: Ventajas de Usar Promesas

Las promesas ofrecen varias ventajas sobre el uso tradicional de callbacks para manejar operaciones asíncronas:

  1. Mejor Legibilidad: El código es más fácil de entender y menos anidado.
  2. Manejo de Errores Simplificado: Es posible capturar errores en cualquier punto de la cadena con catch().
  3. Evita el “Callback Hell”: Las promesas permiten encadenar operaciones de manera más clara y lineal.

Conclusión

Las promesas en JavaScript proporcionan una forma más limpia y estructurada de manejar operaciones asíncronas, resolviendo muchos de los problemas que surgen con los callbacks. Entender cómo funcionan, cómo crearlas y cómo manejar sus resultados te permitirá escribir código más eficiente y fácil de mantener.

En el siguiente artículo, abordaremos el encadenamiento de promesas, cómo se puede simplificar el flujo de trabajo y qué técnicas usar para manejar la programación asíncrona de manera efectiva.

+1
0
+1
0