Trabajar con código asíncrono en JavaScript tiene varias formas, y una de las más claras y legibles es async y await. Esta sintaxis permite escribir funciones que manejan promesas de manera secuencial, sin perder las ventajas del procesamiento asíncrono. A continuación se explica cómo funciona, cómo se compara con las promesas tradicionales y cómo consumir una API pública paso a paso.
¿Qué es async y await y por qué mejora la legibilidad del código asíncrono?
Cuando se marca una función con la palabra reservada async, esa función automáticamente devuelve una promesa [01:23]. Esto significa que el motor de JavaScript toma el código dentro de ella y lo envía a la sección de Web API, donde se resuelve de forma independiente. Una vez resuelta, el event loop se encarga de devolver el resultado al call stack para que se ejecute el callback correspondiente [00:38].
La diferencia principal frente a las promesas encadenadas con .then() es la legibilidad. Con async y await, los pasos se leen de arriba hacia abajo, como si fueran código síncrono, aunque por debajo siguen siendo asíncronos [01:50].
¿Cómo funciona el flujo con promesas y then?
Antes de pasar a async y await, conviene entender el enfoque tradicional. El fetch es una Web API que también retorna una promesa [02:10]. Al consumir una API pública, por ejemplo la de Rick and Morty, el flujo con promesas luce así:
- Se llama a
fetch() pasando la URL del API.
- El primer
.then() recibe la respuesta y la convierte a JSON con response.json().
- Un segundo
.then() toma esa data ya convertida y la utiliza, por ejemplo imprimiéndola en consola.
- El
.catch() captura cualquier error que ocurra en la cadena.
Este patrón funciona correctamente. Al ejecutar la función fetchData(), la consola muestra los primeros veinte personajes que el API devuelve por defecto [04:42].
¿Cómo se transforma esa misma función a async y await?
Para convertir la función anterior se necesitan pocos cambios, pero son significativos [05:20]:
- Se agrega la palabra async antes de la declaración de la función.
- Se reemplaza la cadena de
.then() por variables que usan await.
- Se envuelve el código en un bloque try catch para manejar errores.
El bloque try contiene el código que debe ejecutarse correctamente. Si algo falla, el control pasa automáticamente al bloque catch, que recibe el error [05:55]. Esta estructura es el equivalente directo del .catch() en promesas tradicionales.
Dentro del try, el código queda así:
javascript
async function fetchData() {
try {
const response = await fetch('https://rickandmortyapi.com/api/character');
const data = await response.json();
console.log(data);
} catch (error) {
console.log(error);
}
}
La palabra await le indica al motor que debe esperar a que la promesa del fetch se resuelva antes de continuar con la siguiente línea [06:30]. Primero se espera la respuesta del servidor y se guarda en response. Después se espera a que esa respuesta se convierta a JSON y se almacena en data. Finalmente se imprime el resultado.
¿Qué resultado se obtiene al ejecutar la función con async y await?
Al llamar a fetchData() en el navegador, el resultado es idéntico al obtenido con promesas encadenadas: una promesa resuelta de forma exitosa que contiene veinte personajes de Rick and Morty [08:05]. La consola muestra que se trata de una promesa completada, lo que confirma que async y await no cambia el mecanismo interno, solo la forma en que se escribe.
Algunos puntos importantes para recordar:
- async convierte cualquier función en una que retorna una promesa.
- await solo puede usarse dentro de funciones marcadas como async.
- try catch reemplaza al
.catch() para el manejo de errores.
- El fetch es una Web API independiente que trabaja de forma asíncrona y devuelve una promesa.
Existen múltiples APIs públicas para practicar, como la de Pokémon, Star Wars o Rick and Morty [03:00]. Elegir cualquiera de ellas permite experimentar con fetch, promesas y async/await hasta dominar el flujo asíncrono.
Si ya trabajas con promesas y quieres que tu código sea más fácil de leer y mantener, prueba reescribir tus funciones con async y await y comparte cómo te fue.