Promesas, async/await y la API fetch con una línea de tiempo del event loop paso a paso y 15 ejemplos que puedes editar y ejecutar: JSON, formularios, errores, peticiones en paralelo, AbortController y reintentos.
Una promesa representa un resultado que llega más tarde. Las funciones async devuelven promesas, y await pausa esa función hasta que una se resuelve. fetch(url) devuelve una promesa de un Response: comprueba response.ok y luego haz await response.json(). Envuelve los await en try y catch, usa Promise.all para peticiones en paralelo y AbortController para cancelar.
El patrón que necesitan la mayoría de las páginas
Empieza por la línea de tiempo para ver por qué el código que va después de un await puede ejecutarse antes que él. Luego edita cualquier ejemplo y se vuelve a ejecutar al momento. Aquí las peticiones usan URL data: o servidores simulados, así que nada sale de tu navegador.
Ninguna en lo que pueden hacer: async/await está construido sobre las promesas. Una función async siempre devuelve una promesa, y await desenvuelve una. Se lee como código normal paso a paso, lo que facilita gestionar los errores con try y catch.
fetch trata cualquier respuesta HTTP como una petición correcta, porque el servidor sí respondió. Solo rechaza ante fallos de red o una petición cancelada. Comprueba tú mismo response.ok o response.status.
Los callbacks de las promesas van a la cola de microtareas, que se vacía por completo después del script actual. Un callback de temporizador es una tarea, que espera a la siguiente vuelta del event loop.
Crea un AbortController, pasa controller.signal en las opciones de fetch y ejecuta controller.abort(). La promesa de fetch se rechaza con un error llamado AbortError.
Sí, dentro de módulos JavaScript (script type="module" o cualquier módulo ES empaquetado). En los scripts clásicos, envuelve el código en una función async.
Primero se ejecutan las líneas síncronas, luego cada callback de promesa en cola (microtareas) y después el temporizador (una tarea). Cambia el orden y vuelve a ejecutarlo.
Una promesa se resuelve una sola vez: resolve da un valor, reject da un error. then y catch se ejecutan más tarde, nunca al instante.
await pausa solo la función async en la que está. La línea que va después de la llamada a main() se ejecuta antes de que main termine.
Dentro de una función async, un await rechazado lanza un error, así que try y catch funcionan como siempre. finally es el sitio para ocultar un indicador de carga.
fetch devuelve un Response; .json() lee e interpreta el cuerpo, que es un segundo await. Este usa una URL data: para que funcione sin conexión.
fetch solo rechaza cuando la petición no se puede hacer en absoluto (sin conexión, bloqueada, URL incorrecta). Un 404 o un 500 se resuelve con normalidad con ok en false, así que compruébalo siempre.
FormData lee cada campo con nombre. Aquí la petición se construye pero no se envía, y se imprime su cuerpo para que veas exactamente lo que recibiría un servidor.
Envía JSON convirtiéndolo en cadena y definiendo tú mismo la cabecera Content-Type; fetch no hace ninguna de las dos cosas con objetos simples.
Qué función de promesas usar
Esperar una llamada cada vez suma las esperas. Iniciarlas todas y hacer await de Promise.all solo espera lo que tarde la más lenta.
Promise.all rechaza en cuanto una falla. allSettled espera a todas y te dice cuáles funcionaron, lo que encaja con paneles de widgets independientes.
Lanzar cientos de peticiones a la vez puede activar los límites de tasa. Este pequeño pool mantiene como máximo tres en curso.
Pasa controller.signal a fetch y ejecuta abort() para detenerlo. La promesa se rechaza con un AbortError, que normalmente ignoras.
AbortSignal.timeout(ms) crea una señal que se cancela sola. Con fetch, el nombre del error es TimeoutError, así que puedes distinguirlo de una cancelación del usuario.
Reintenta solo los errores que pueden pasar, como un tiempo de espera agotado o un 503, y espera más cada vez para que un servidor saturado pueda recuperarse.
Espera a una pausa al escribir y cancela la petición anterior cuando empiece una nueva, para que una respuesta lenta y antigua nunca pueda sobrescribir otra más reciente.
¿Tienes una respuesta que necesitas leer? Pégala en el
Pila de llamadas
Microtareas
Cola de tareas
Consola
Paso {i} de {n}.
Atrás
Siguiente paso
Pausa
Reproducir
Reiniciar
Empieza gratis · Sin tarjeta de crédito