La asincronía en JavaScript es la clave para que tus aplicaciones respondan rápido sin bloquearse, incluso cuando ejecutan tareas que tardan, como llamadas a una API o lecturas de archivos. Aquí entiendes cómo funciona el modelo single thread, qué es el event loop y cómo usar callbacks y promesas con ejemplos reales.
¿Por qué JavaScript es asíncrono si solo tiene un hilo?
JavaScript ejecuta el código en un único hilo, lo que significa que las instrucciones corren una tras otra. Pero gracias al event loop, puede manejar operaciones que tardan (timers, peticiones a APIs, lecturas de archivos) sin frenar el resto del programa.
Mira este patrón clásico con setTimeout [01:54]:
js
console.log("1, inicio");
setTimeout(() => {
console.log("2, timeout");
}, 1000);
console.log("3, fin");
A simple vista parece que verías 1, 2 y 3 en orden. Pero el resultado real es: inicio, fin, timeout. ¿La razón? El setTimeout se manda a una pila de ejecución y el programa sigue corriendo mientras espera.
¿Qué es el event loop en JavaScript? Es el mecanismo que permite a JavaScript, aun siendo single thread, postergar tareas que tardan y ejecutarlas cuando estén listas, sin bloquear el resto del código.
¿Cómo funcionan los callbacks y por qué cuidarlos?
Un callback es una función que pasas como argumento a otra función para que se ejecute cuando se complete cierta operación. Es la forma más antigua de manejar asincronía en JavaScript.
¿Cómo se escribe un callback básico?
Mira este ejemplo donde simulamos una operación que tarda dos segundos [05:36]:
js
function obtenerDatos(callback) {
setTimeout(() => {
callback("datos obtenidos");
}, 2000);
}
obtenerDatos((resultado) => {
console.log(resultado);
});
La función obtenerDatos recibe otra función como parámetro y la ejecuta cuando termina su tarea. Simple y útil para tareas puntuales.
¿Qué es el callback hell y cómo lo identificas?
El problema aparece cuando necesitas encadenar varias operaciones dependientes: obtener un usuario, después sus notas, después procesarlas. Esa anidación profunda se conoce como callback hell [08:41].
Los riesgos son concretos:
- Un typo en una función interna rompe toda la cadena.
- La lectura del código se vuelve difícil con cada nivel de indentación.
- El manejo de errores se duplica en cada paso.
¿Cuándo evitar callbacks anidados? Si tu lógica requiere más de tres niveles de anidación, mejor pasa a promesas o a async/await. La legibilidad y el mantenimiento te lo agradecen.
¿Qué son las promesas y cómo se usan?
Una promesa representa un valor que puede estar disponible ahora, en el futuro o nunca. Tiene tres estados: pendiente, cumplida o rechazada [11:36]. Es la forma más utilizada hoy para trabajar asincronía en JavaScript moderno.
¿Cómo se construye una promesa con resolve y reject?
La estructura usa new Promise y recibe una función con dos parámetros: resolve (cuando todo sale bien) y reject (cuando hay un error).
js
const promesa = new Promise((resolve, reject) => {
const exito = true;
setTimeout(() => {
if (exito) {
resolve("operación exitosa");
} else {
reject(new Error("algo salió mal"));
}
}, 1000);
});
Fíjate en new Error: en lugar de mandar un simple string, esto entrega información más completa (como el trace) cuando algo falla, tanto en el navegador como en Node.js.
¿Cómo capturar el resultado con then y catch?
Una vez creada la promesa, la consumes con .then para el caso exitoso y .catch para el error [15:37]:
js
promesa
.then((mensaje) => {
console.log(mensaje);
})
.catch((error) => {
console.error(error.message);
});
Si exito es true, verás operación exitosa. Si lo cambias a false, el flujo entra al .catch y muestra algo salió mal. La estructura queda mucho más limpia que con callbacks anidados.
¿Qué diferencia hay entre callback y promesa? El callback pasa una función como argumento que se ejecuta al terminar. La promesa devuelve un objeto con estados que encadenas con .then y .catch, ofreciendo mejor manejo de errores y código más legible.
¿Qué casos de uso reales tiene la asincronía?
Entender cuándo aplicar estos patrones te ayuda a escribir código que escala:
- Llamadas a APIs externas que tardan milisegundos o segundos.
- Lectura de archivos del sistema, donde el tiempo depende de la capacidad de la máquina.
- Timers para diferir acciones, animaciones o validaciones.
- Eventos del navegador como clics, scroll o carga de recursos.
En todos estos casos, la asincronía evita que tu interfaz se congele o que tu servidor se bloquee mientras espera respuestas.
El siguiente paso natural es async/await, una sintaxis que te permite escribir código asíncrono que se lee como si fuera síncrono. Si ya practicaste callbacks y promesas, vas a sentir el salto en claridad. Cuéntame en los comentarios qué tarea asíncrona estás resolviendo en tu proyecto actual.