Damián De Luca - Capacitación & Desarrollo Web

Cómo usar async y await en JavaScript

JavaScript
Async y Await en JavaScript

En el desarrollo web moderno, la capacidad de manejar código asíncrono de manera eficiente es crucial. Como programadores y desarrolladores, nos encontramos con operaciones que requieren tiempo, como llamadas a APIs externas o consultas a bases de datos. Para simplificar la forma en que manejamos estos procesos en JavaScript, se introdujeron las funciones asíncronas (async) y la palabra clave await para esperar el resultado.

Estas características las explico en mis cursos para que mis alumnos comprendan sus beneficios frentes a otras alternativas. A lo largo de este artículo, exploraremos las razones detrás de la introducción de async y await. Analizaremos sus principales beneficios, y cómo podemos utilizarlos con un ejemplo práctico que simula una llamada a una API local con datos JSON.

¿Por qué se introdujeron async y await?

Antes de que existieran async y await, el manejo de código asíncrono en JavaScript se realizaba a través de promesas y callbacks. Sin embargo, estas soluciones, aunque útiles, a menudo creaban problemas de legibilidad y mantenimiento, especialmente cuando se tenían múltiples promesas encadenadas.

El propósito de async y await es hacer que el código asíncrono se vea y funcione de manera más ordenada, sin sacrificar la eficiencia del flujo no bloqueante de JavaScript.

Beneficios de async y await

Las razones de la introducción de estas nuevas características están claras. A continuación veamos algunas de sus ventajas más importantes:

  1. Código más legible: el código escrito con async y await se lee de manera más secuencial y clara, eliminando la necesidad de manejar manualmente las promesas con .then() y .catch(). Esto lo hace más fácil de entender, especialmente en proyectos grandes.
  2. Mejor manejo de errores: con el uso de bloques try/catch, es posible capturar errores en las operaciones asíncronas de una manera mucho más limpia que usando catch en promesas encadenadas.
  3. Mayor productividad: al escribir código más legible y fácil de depurar, los equipos de desarrollo pueden trabajar de manera más eficiente, reduciendo el tiempo de desarrollo y los posibles errores. Siempre explico en mis capacitaciones que esto resulta fundamental tanto para estudiantes que buscan aprender buenas prácticas como para empresas que desean escalar sus aplicaciones web.

Ejemplo práctico con una Rest API local

Para ilustrar el uso de async y await, vamos a crear un ejemplo donde simulamos una llamada a una API local. Esta API devolverá un array de nombres y países de América Latina en formato JSON, y los mostraremos en una lista dentro de una página web.

En este ejemplo, la API se ejecutará en localhost y devolverá datos en formato JSON. Podemos hacer uso de fetch para consumir estos datos.

Supongamos que tenemos un archivo data.json alojado en nuestra API local que contiene la siguiente estructura de información:

[
  { "name": "Carlos", "country": "México" },
  { "name": "Ana", "country": "Argentina" },
  { "name": "Luisa", "country": "Chile" },
  { "name": "Paola", "country": "Colombia" },
  { "name": "José", "country": "Perú" }
]

A continuación, crearemos una función async que utilizará fetch para consumir los datos de la API local y luego los mostrará en una lista HTML.

async function fetchNames() {
  try {
    // Llamamos a la API local para obtener los datos. La URL varía según la implementación
    const response = await fetch('http://localhost:3000/data.json');

    // Si la respuesta no es exitosa, lanzamos un error
    if (!response.ok) {
      throw new Error('Error al obtener los datos');
    }

    // Convertimos la respuesta en un formato JSON
    const data = await response.json();

    // Seleccionamos el elemento donde mostraremos los nombres y países obtenidos. En este caso una lista identificada por una id (name-list)
    const listElement = document.getElementById('name-list');

    // Iteramos sobre los datos y los añadimos a la lista
    data.forEach(item => {
      const listItem = document.createElement('li');
      listItem.textContent = `${item.name} - ${item.country}`;
      listElement.appendChild(listItem);
    });
  } catch (error) {
    console.error("Error en la llamada a la API:", error);
  }
}

// Ejecutamos la función cuando el DOM esté listo
document.addEventListener('DOMContentLoaded', fetchNames);

A continuación veremos el código básico del HTML donde se visualizarán los resultados devueltos por la API:

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Lista de Nombres y Países</title>
</head>
<body>
  <h1>Nombres y Países de América Latina</h1>
  <ul id="name-list"></ul>

  <script src="app.js"></script>
</body>
</html>

El ejemplo explicado paso a paso

Ahora vamos a analizar las partes del ejemplo:

  1. La función fetchNames: utilizamos async para declarar que esta función trabajará con operaciones asíncronas. Dentro de la función, usamos await para esperar la resolución de la llamada a la API mediante fetch.
  2. fetch para la llamada a la API: fetch es una API nativa de JavaScript que se utiliza para realizar solicitudes HTTP. En este caso, llamamos a nuestra API local y obtenemos un archivo data.json con los datos.
  3. Manejo de errores: en este caso es recomendable emplear try/catch para asegurarnos de que si ocurre algún error (como una falla en la conexión a la API o una respuesta no válida), este se capture y se pueda manejar correctamente.
  4. Interacción con el DOM: una vez que obtenemos los datos, iteramos sobre el array resultante y creamos elementos <li> para añadirlos a la lista en la lista (la <ul> cuya id es name-list).

Conclusión

Este ejemplo nos permite entender cómo manejar código asíncrono de manera ordenada y clara utilizando async y await. Además, muestra cómo consumir APIs y procesar datos en un contexto realista, habilidades fundamentales para desarrolladores web.

Adoptar estas características en sus proyectos es clave para mejorar la legibilidad y mantenibilidad del código. Esto facilita la colaboración entre equipos y la escalabilidad de las aplicaciones. Además, el manejo de errores más eficiente y la capacidad de realizar múltiples llamadas asíncronas de manera secuencial son esenciales en aplicaciones empresariales que dependen de datos externos.

La introducción de async y await ha sido un cambio significativo en la forma en que escribimos código asíncrono en JavaScript. No solo nos permite escribir código más legible y limpio, sino que también facilita el manejo de errores y mejora la productividad tanto en proyectos educativos como empresariales. Adoptar estas herramientas es una excelente manera de mejorar nuestras habilidades como desarrolladores y crear aplicaciones más eficientes.

Para ver más ejemplos podremos leer el siguiente artículo de MDN: Función async.

Salir de la versión móvil