Promesas y async/await
JavaScript, tradicionalmente, es de "un solo hilo" (single-threaded). Esto significa que solo puede hacer una cosa a la vez.
Si le pides a JavaScript que descargue un archivo pesado de 500MB de internet de forma síncrona (normal), la página web entera se "congelaría" completamente hasta que el archivo termine de descargar. No podrías hacer click en botones ni hacer scroll.
Para evitar esto, JavaScript usa la asincronía. Le dice al navegador: "Ve descargando este archivo en el fondo. Yo sigo ejecutando el resto de mi código. Avísame cuando termines".
Promesas (Promises)
Una Promesa es un objeto que representa la terminación o el fracaso eventual de una operación asíncrona.
Piensa en una promesa como pedir una hamburguesa en un restaurante:
- Pagas y te dan un ticket (La promesa). La hamburguesa todavía no existe (estado Pending o Pendiente).
- Te vas a sentar y sigues hablando con tus amigos (JavaScript sigue ejecutando otro código).
- Eventualidad A (Éxito): Tu número suena y te entregan la comida. La promesa se resolvió (Fulfilled / Resuelta).
- Eventualidad B (Error): El cocinero sale y te dice que se quedaron sin carne. La promesa fracasó (Rejected / Rechazada).
// Simulación de una promesa (normalmente estas te las entregan APIs externas, no las creas a mano tan seguido)
const miPedido = new Promise((resolve, reject) => {
let exito = true;
setTimeout(() => { // Simulando que toma 2 segundos preparar la orden
if (exito) {
resolve("Hamburguesa con queso entregada"); // Éxito!
} else {
reject("Error: Nos quedamos sin pan"); // Fracaso!
}
}, 2000);
});
// ¿CÓMO CONSUMIR LA PROMESA? (La forma antigua con .then)
miPedido
.then((comida) => {
// Se ejecuta SOLO SI fue resolve()
console.log("¡Qué rico!", comida);
})
.catch((error) => {
// Se ejecuta SOLO SI fue reject()
console.error("Oh no:", error);
});
⭐️ La Forma Moderna: async / await
Aunque .then() y .catch() funcionan bien, cuando tienes muchas promesas anidadas (promesa dentro de promesa dentro de promesa) el código se vuelve muy difícil de leer.
En 2017 se introdujeron las palabras clave async y await, construidas sobre las Promesas, que nos permiten escribir código asíncrono que se lee casi exactamente igual que el código síncrono normal.
1. async (La función asíncrona)
Poner la palabra async antes de una función significa dos cosas:
- Esa función automáticamente devuelve una Promesa siempre.
- Activa el permiso para usar la palabra mágica
awaitdentro de ella. (No puedes usarawaiten una función normal).
2. await (Pausa y espera)
Hace que la ejecución de ESA MISMA FUNCIÓN ASÍNCRONA (nada más) se detenga temporalmente hasta que la Promesa a su derecha se resuelva o falle.
// Usando la misma promesa de "miPedido" del ejemplo anterior
const irAlRestaurante = async () => {
console.log("1. Llegando al restaurante...");
console.log("2. Ordenando...");
try {
// En vez de usar .then, aquí "pausamos" hasta tener el resultado.
const comida = await miPedido;
console.log("3. Disfrutando la", comida); // Solo 2 segundos después
} catch (error) {
// En vez de usar .catch
console.error("3. Hubo un problema:", error);
}
};
irAlRestaurante();
console.log("--- El mundo exterior sigue girando ---");
/* SALIDA ESPERADA:
1. Llegando al restaurante...
2. Ordenando...
--- El mundo exterior sigue girando ---
(2 segundos de pausa en la función asíncrona...)
3. Disfrutando la Hamburguesa con queso entregada
*/