L53 - Async / Await
🧠 Concepto
Section titled “🧠 Concepto”async y await son sugar syntax sobre Promesas que permite escribir código asíncrono con una apariencia síncrona. Fue introducido en ES2017 (ES8) y hoy es el estándar de facto para manejar asincronía en JavaScript.
💻 async function
Section titled “💻 async function”Declarar una función como async hace que siempre devuelva una Promise:
async function saludar() { return 'Hola'; // automáticamente: Promise.resolve('Hola')}
saludar().then(console.log); // 'Hola'Si la función lanza una excepción, devuelve una Promise rechazada:
async function fallar() { throw new Error('Oops');}
fallar().catch(console.error); // Error: Oops💻 await
Section titled “💻 await”await pausa la ejecución de la función async hasta que la Promise se resuelva o rechace:
async function obtenerUsuario(id) { const respuesta = await fetch(`/api/usuarios/${id}`); const usuario = await respuesta.json(); return usuario;}⚠️ Solo se puede usar
awaitdentro de una funciónasync(salvo top-level await en módulos).
📝 try/catch con async/await
Section titled “📝 try/catch con async/await”Para manejar errores se usa try/catch tradicional:
async function cargarDatos() { try { const res = await fetch('/api/datos'); if (!res.ok) throw new Error(`HTTP ${res.status}`); const datos = await res.json(); return datos; } catch (error) { console.error('Error al cargar datos:', error); return null; }}Alternativa: .catch() en la llamada
Section titled “Alternativa: .catch() en la llamada”const datos = await cargarDatos().catch(err => { console.error(err); return null;});🎯 Flujo secuencial vs paralelo
Section titled “🎯 Flujo secuencial vs paralelo”Secuencial (lento)
Section titled “Secuencial (lento)”async function secuencial() { const a = await fetch('/api/a'); // espera const b = await fetch('/api/b'); // espera de nuevo // Tiempo total: suma de ambos tiempos}Paralelo (rápido)
Section titled “Paralelo (rápido)”async function paralelo() { const [a, b] = await Promise.all([ fetch('/api/a'), fetch('/api/b'), ]); // Tiempo total: el mayor de los dos tiempos}🎯 Regla de oro: si las operaciones no dependen entre sí, ejecútalas en paralelo con
Promise.all().
💻 Ejemplo práctico
Section titled “💻 Ejemplo práctico”async function obtenerDashboard(usuarioId) { try { // Paralelo: datos independientes const [usuario, notificaciones] = await Promise.all([ fetch(`/api/usuarios/${usuarioId}`).then(r => r.json()), fetch(`/api/notificaciones/${usuarioId}`).then(r => r.json()), ]);
// Secuencial: depende del usuario const pedidos = await fetch(`/api/pedidos/${usuario.id}`).then(r => r.json());
return { usuario, notificaciones, pedidos }; } catch (error) { console.error('Dashboard falló:', error); throw error; }}⚠️ Async/await vs .then()
Section titled “⚠️ Async/await vs .then()”| Async/await | .then() |
|---|---|
| Más legible, parece síncrono | Más verboso con cadenas largas |
| try/catch familiar | .catch() anidado |
| Depuración más fácil (breakpoints) | Menos intuitivo en depuración |
| Ideal para flujos complejos | Útil para transformaciones rápidas |
Ambos son igual de válidos. async/await es la opción recomendada en la mayoría de los casos por su claridad.
🎯 Top-level await
Section titled “🎯 Top-level await”En módulos se puede usar await sin estar dentro de una función async:
// config.js (módulo)const response = await fetch('/config.json');export const config = await response.json();El módulo espera a que la Promise se resuelva antes de que otros módulos puedan importarlo. Muy útil para inicialización asíncrona.
⚠️ El top-level await bloquea la carga del módulo. Úsalo con cuidado para no retrasar la aplicación innecesariamente.
📝 Buenas prácticas
Section titled “📝 Buenas prácticas”- Siempre usa try/catch o proporciona un
.catch(). - Paraleliza operaciones independientes con
Promise.all(). - No abuses de
awaitsecuencial si no es necesario. - Los bucles
for...ofconawaitse ejecutan secuencialmente; para paralelo usaPromise.all()con un.map().
// Secuencial (uno tras otro)for (const url of urls) { const res = await fetch(url);}
// Paralelo (todos a la vez)const resultados = await Promise.all(urls.map(url => fetch(url)));