W3docs

JavaScript async/await

Aprende JavaScript async/await: funciones async, await, manejo de errores con try/catch, ejecución secuencial vs paralela con Promise.all, await de nivel superior y errores comunes.

La sintaxis async/await es la forma moderna y legible de trabajar con código asíncrono en JavaScript. Está construida directamente sobre las promesasasync/await no las reemplaza, sino que ofrece una sintaxis más limpia para consumirlas. En lugar de encadenar callbacks .then(), escribes código que se lee de arriba a abajo como código síncrono ordinario, mientras el motor gestiona la espera en segundo plano.

Este capítulo explica qué devuelven las funciones async, cómo await pausa la ejecución, el manejo de errores con try...catch, la ejecución de tareas de forma secuencial frente a paralela, await de nivel superior en módulos y los errores más comunes que cometen los desarrolladores.

Las funciones async siempre devuelven una promesa

Marcar una función como async hace dos cosas: permite usar await dentro del cuerpo de la función y garantiza que la función devuelva una promesa. Cualquier valor que se devuelva con return se convierte en el valor resuelto de esa promesa; si se lanza una excepción con throw, la promesa se rechaza.

javascript— editable

Dado que el valor de retorno es una promesa, quien llama a la función debe usar await (o .then()) para leer el valor real. Un error frecuente en principiantes es esperar que greet() devuelva 'Hello' directamente.

await pausa hasta que la promesa se resuelve

El operador await solo puede usarse dentro de una función async (o en el nivel superior de un módulo — ver más abajo). Pausa la función hasta que la promesa a su derecha se resuelve: si se cumple, devuelve el valor resuelto; si se rechaza, lanza el motivo del rechazo.

Es importante destacar que await no bloquea todo el programa. Solo suspende la función asíncrona actual; el resto del código y el bucle de eventos siguen ejecutándose.

javascript— editable

Puedes usar await con cualquier valor, no solo con una promesa. Los valores que no son promesas se envuelven y se resuelven de inmediato, así que await 5 simplemente devuelve 5.

Manejo de errores con try...catch

Una de las mayores ventajas de async/await es que puedes manejar errores con el mismo try...catch que ya usas para código síncrono. Una promesa rechazada se convierte en una excepción lanzada en el punto del await, que catch puede interceptar.

javascript— editable

Si no capturas un rechazo, se convierte en un rechazo de promesa no manejado. Para profundizar en la mecánica del lado de las promesas, consulta manejo de errores con promesas.

Un ejemplo real: obtener datos e informar los fallos de forma clara.

javascript— editable

Observa la verificación explícita de response.ok: fetch solo rechaza ante fallos de red, no ante códigos de error HTTP como 404 o 500, por lo que debes inspeccionar la respuesta tú mismo.

Ejecución secuencial frente a paralela

Aquí es donde await se usa de forma incorrecta con más frecuencia. Cuando usas await en operaciones una tras otra, estas se ejecutan de forma secuencial — cada una espera a que termine la anterior. Eso es correcto solo cuando una tarea posterior depende del resultado de una anterior.

Secuencial (cuando las tareas dependen unas de otras)

async function pipeline() {
  const user = await getUser(1);          // step 1
  const posts = await getPosts(user.id);  // needs user.id, so must wait
  return posts;
}

Paralela (cuando las tareas son independientes)

Si las tareas no dependen entre sí, esperarlas en secuencia desperdicia tiempo. Iníscialas todas y luego espéralas juntas con Promise.all:

javascript— editable

Promise.all se rechaza en cuanto cualquiera de sus promesas se rechaza. Si en cambio quieres esperar a todas las promesas independientemente del éxito o el fracaso, usa Promise.allSettled. Consulta la API de promesas para ver la familia completa de combinadores.

await de nivel superior en módulos

Dentro de módulos ES (<script type="module"> o archivos .mjs), puedes usar await en el nivel superior sin envolverlo en una función async:

// data.mjs — an ES module
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const todo = await response.json();

export { todo };

Esto resulta útil para la inicialización de módulos, como cargar configuración antes de que las exportaciones del módulo estén listas. Ten en cuenta que un módulo que usa await de nivel superior retrasa la evaluación de cualquier módulo que lo importe. El await de nivel superior solo funciona en módulos — usarlo en un script clásico o en una función normal es un error de sintaxis.

Errores comunes

No uses await dentro de un bucle para trabajo independiente

Usar await dentro de un bucle for obliga a las iteraciones a ejecutarse de una en una. Si las iteraciones son independientes, esto es innecesariamente lento.

javascript— editable

Usa await dentro de un bucle solo cuando cada iteración dependa genuinamente de la anterior, o cuando necesites limitar el número de solicitudes simultáneas.

Otros errores frecuentes

  • forEach ignora los callbacks async. array.forEach(async ...) no espera las promesas. Usa un bucle for...of o Promise.all(array.map(...)) en su lugar.
  • No olvides await. Llamar a una función async sin await (ni .then()) devuelve una promesa pendiente y silencia los errores. Los linters suelen señalar las promesas "flotantes".
  • fetch no rechaza ante errores HTTP. Comprueba siempre response.ok, como se muestra arriba.

Conclusión

async/await hace que el JavaScript asíncrono se lea como código síncrono mientras mantiene el bucle de eventos libre. Recuerda lo esencial: cada función async devuelve una promesa, await pausa solo la función actual, los errores fluyen a través de try...catch, y debes ejecutar tareas independientes en paralelo con Promise.all en lugar de esperarlas una a una. Para consolidar la base que sustenta esta sintaxis, revisa las promesas y el encadenamiento de promesas.

Práctica

Práctica
¿Cuál es la función de la palabra clave 'async' en JavaScript?
¿Cuál es la función de la palabra clave 'async' en JavaScript?
Was this page helpful?