Ejemplos de Uso de Promesas en JavaScript para Programación Asíncrona

La programación asíncrona es un paradigma crucial en el mundo del desarrollo web, especialmente cuando se trata de JavaScript. Las promesas son una pieza esencial en este escenario, proporcionando una forma poderosa y manejable de trabajar con operaciones que no se completan inmediatamente, como las solicitudes de red. En este artículo, nos sumergiremos en el concepto de promesas en JavaScript y veremos múltiples ejemplos que ilustran su uso en diferentes situaciones comunes al programar en el lado del cliente.

JavaScript, siendo un lenguaje de programación orientado a eventos, suele presentar desafíos cuando lidiemos con código que no se ejecuta secuencialmente. Por ello, comprender las promesas y cómo utilizarlas correctamente puede marcar la diferencia en la calidad y la legibilidad de nuestro código. Sin más preámbulos, iniciemos con una introducción básica sobre qué son las promesas y cómo pueden transformar nuestra forma de programar en JavaScript.

Introducción a las Promesas en JavaScript

Una promesa en JavaScript es un objeto que representa la eventual finalización o fracaso de una operación asíncrona. Cada promesa pasa por diferentes estados: pendiente, cumplida o rechazada. Cuando creamos una promesa, esta comienza en estado pendiente. Según se resuelve satisfactoriamente o se rechaza debido a un error, la promesa pasa a estar cumplida o rechazada, respectivamente.

El poder de las promesas radica en su capacidad para manejar el código asíncrono de una manera más predecible y estructurada. En lugar de depender de callbacks anidados, que pueden llevar a lo que se conoce como ‘callback hell’, las promesas ofrecen una sintaxis más clara y una mejor gestión de los errores a través de sus métodos .then(), .catch() y .finally().

Ejemplo Básico de Promesa

Para ilustrar el concepto básico de una promesa, veamos un simple ejemplo. Imagina que tienes una función que verifica la disponibilidad de un artículo en un inventario. Esta verificación podría tomar algo de tiempo, por lo que en lugar de bloquear la ejecución, la colocamos dentro de una promesa.

function verificarDisponibilidad(articulo) {
  return new Promise((resolve, reject) => {
    // Simulamos una operación que toma tiempo con setTimeout
    setTimeout(() => {
      const inStock = Math.random() > 0.5; // Aleatoriamente disponible o no
      if (inStock) {
        resolve(`El artículo ${articulo} está disponible.`);
      } else {
        reject(new Error(`El artículo ${articulo} no está en stock.`));
      }
    }, 2000);
  });
}

verificarDisponibilidad('computadora').then(mensaje => {
  console.log(mensaje);
}).catch(error => {
  console.error(error);
});

En este ejemplo, la función ‘verificarDisponibilidad’ devuelve una promesa que se resolverá con éxito si el artículo está en stock o se rechazará con un error si no lo está. Usamos ‘setTimeout’ para simular una operación de red. Luego, manejamos tanto la resolución como el rechazo con los métodos .then() y .catch(), respectivamente.

Encadenando Promesas

Uno de los mayores beneficios de las promesas es su capacidad para encadenarse. Esto significa que podemos realizar una serie de operaciones asíncronas de manera secuencial sin caer en la trampa de los callbacks anidados. Veamos cómo se ve esto en la práctica con un ejemplo que encadena varias promesas.

const verificarCredito = (cliente) => {
  return new Promise((resolve, reject) => {
    // Código que verifica el crédito del cliente
  });
};

const procesarPedido = (pedido) => {
  return new Promise((resolve, reject) => {
    // Código que procesa el pedido
  });
};

verificarCredito('Juan Pérez')
  .then(() => {
    return procesarPedido({ articulo: 'computadora', cantidad: 1 });
  })
  .then(result => {
    console.log('Pedido procesado:', result);
  })
  .catch(error => {
    console.error('Hubo un error:', error);
  });

En esta secuencia, primero verificamos el crédito del cliente y, si es exitoso, luego procesamos el pedido. Si en algún punto hay un error, el método .catch() lo capturará. Nótese cómo cada .then() devuelve una nueva promesa, lo que permite el encadenamiento.

Uso de async/await con Promesas

ECMAScript 2017 introdujo las palabras clave async y await, ofreciendo una nueva forma de trabajar con promesas. Una función marcada como async indica que siempre devolverá una promesa, y await puede ser utilizado para pausar la ejecución de la función hasta que la promesa a la que está esperando se resuelva. Vamos a explorar cómo esto simplifica aún más el trabajo con código asíncrono.

Consideremos una función asincrónica que realiza una solicitud de red para obtener datos de usuario.

async function obtenerDatosUsuario(userId) {
  try {
    let respuesta = await fetch(`https://api.misitio.com/usuarios/${userId}`);
    let datos = await respuesta.json();
    console.log(datos);
  } catch (error) {
    console.error('Error al obtener los datos del usuario:', error);
  }
}

obtenerDatosUsuario('user123');

En este ejemplo, la palabra clave await se utiliza para esperar a que la solicitud de red se complete antes de convertir la respuesta en JSON. En caso de que algo salga mal durante la solicitud, el bloque try/catch captura cualquier excepción y la maneja adecuadamente. Con async/await, el código asincrónico parece y se comporta un poco más como código sincrónico tradicional, lo que lo hace más fácil de entender y mantener.

Te puede interesar

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *