Asincronía y APIs
💡 🎯 Al terminar esta lección podrás…
- Explicar por qué el código asíncrono no se ejecuta en el orden en que se escribe.
- Usar temporizadores y promesas.
- Escribir funciones con
async/awaitytry/catch. - Pedir datos con
fetchy gestionar los estados de carga, error y vacío.
1.Síncrono y asíncrono
Hasta ahora, cada línea esperaba a que terminara la anterior: es lo síncrono. Pero hay tareas que tardan: pedir datos a un servidor, esperar 3 segundos, leer un archivo. Si JavaScript se quedara esperando sin hacer nada más, la página se congelaría: no podrías ni pulsar un botón.
La solución es lo asíncrono: se inicia la tarea lenta, el programa sigue con lo demás, y cuando la tarea termina, se ejecuta una función con el resultado.
Ejecútalo: el mensaje 2 sale antes que el 3, aunque esté escrito después. setTimeout no detiene el programa: agenda la función para más tarde y continúa. Entender esto es la clave de toda la lección.
📌 Nota · Una sola línea de ejecución
JavaScript hace una cosa a la vez. Lo asíncrono no significa «dos cosas a la vez»: significa que cuando una tarea tiene que esperar (a la red, a un temporizador), el navegador se ocupa de la espera y JavaScript atiende otras cosas mientras tanto.
2.Temporizadores
| Función | Qué hace | Se cancela con |
|---|---|---|
setTimeout(fn, ms) | Ejecuta fn una vez tras ms milisegundos | clearTimeout(id) |
setInterval(fn, ms) | Ejecuta fn cada ms milisegundos | clearInterval(id) |
⚠️ Importante · Limpia tus intervalos
Un setInterval sigue ejecutándose para siempre hasta que lo cancelas. Guarda su id y llama a clearInterval(id) cuando ya no haga falta, o seguirá consumiendo recursos aunque ya no se vea.
3.Promesas
Una promesa (*Promise*) es un objeto que representa un resultado que llegará en el futuro. Siempre está en uno de tres estados:
| Estado | Significa | Cómo reaccionar |
|---|---|---|
| pending (pendiente) | Todavía no hay resultado | — |
| fulfilled (cumplida) | Terminó bien y tiene un valor | .then(valor => …) |
| rejected (rechazada) | Terminó mal y tiene un error | .catch(error => …) |
.then()recibe el valor cuando la promesa se cumple y devuelve otra promesa: se pueden encadenar..catch()atrapa los errores de cualquier paso anterior de la cadena..finally()se ejecuta siempre, salga bien o mal (ideal para quitar un «cargando…»).
4.async / await: promesas con aspecto de código normal
async y await permiten escribir código asíncrono como si fuera síncrono, de arriba abajo, mucho más legible que las cadenas de .then():
| Palabra | Qué hace |
|---|---|
async function f() | La función siempre devuelve una promesa |
await promesa | Pausa solo esa función hasta que la promesa se cumpla y da su valor. Solo se puede usar dentro de una función async (o en un módulo) |
try { … } catch (e) { … } | Atrapa los errores (promesas rechazadas) de los await |
5.Pedir datos a internet con fetch
fetch(url) hace una petición HTTP y devuelve una promesa con la respuesta. Es lo que usan las páginas para traer datos de una API (un servicio que ofrece datos en JSON):
async function cargarUsuario(id) {
const respuesta = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
if (!respuesta.ok) { // 404, 500…
throw new Error(`Error ${respuesta.status}`);
}
const usuario = await respuesta.json(); // convertir el cuerpo JSON en un objeto
return usuario;
}
await fetch(url)→ una respuesta (aunque sea un 404:fetchsolo falla si no hay red).- Comprueba
respuesta.ok(truepara códigos 200–299) y lanza un error si no. await respuesta.json()→ los datos como objeto de JavaScript.
📌 Nota · ¿Y si estás sin conexión?
Este ejemplo necesita internet. Si falla, verás el mensaje de error en pantalla: es justo lo que debe pasar, y por eso siempre se envuelve fetch en try…catch. Los ejercicios del curso simulan la red para funcionar siempre.
⚠️ Importante · CORS
Los navegadores bloquean pedir datos a otro dominio salvo que ese servidor lo permita expresamente (cabeceras CORS). Si ves «blocked by CORS policy», no es un error tuyo: el servidor no admite peticiones desde tu página.
6.Varias tareas a la vez
| Función | Hace | Cuándo |
|---|---|---|
Promise.all([…]) | Espera a que todas terminen; falla si una falla | Cargar varias cosas independientes a la vez |
Promise.allSettled([…]) | Espera a todas y da el resultado de cada una | Quieres saber qué salió bien y qué mal |
Promise.race([…]) | La primera que termine | Tiempos límite |
💡 Consejo · No esperes de uno en uno sin necesidad
Si las tareas no dependen unas de otras, lánzalas juntas con Promise.all: tardan lo que tarde la más lenta, no la suma de todas. Es una mejora de rendimiento gratuita.
7.Buena experiencia: cargando, error y vacío
Una pantalla que muestra datos remotos debe contemplar cuatro estados, no solo el feliz:
| Estado | Qué mostrar |
|---|---|
| Cargando | Un indicador («Cargando…», un *spinner*), idealmente con role="status" |
| Éxito | Los datos |
| Vacío | Un mensaje claro («No hay resultados») y no una pantalla en blanco |
| Error | Qué pasó, en lenguaje humano, y cómo reintentar |
async function mostrarDatos() {
estado.textContent = "Cargando…";
boton.disabled = true;
try {
const datos = await obtener();
estado.textContent = datos.length ? "" : "No hay resultados";
pintar(datos);
} catch (error) {
estado.textContent = "No pudimos cargar los datos. Inténtalo de nuevo.";
} finally {
boton.disabled = false; // se ejecuta siempre
}
}
8.Errores frecuentes
- Olvidar
await: obtienes una promesa en lugar del valor (Promise { <pending> }). - Usar
awaitfuera de una funciónasync. - No comprobar
respuesta.ok: un 404 no hace fallar afetch. - Olvidar
.json()o no esperarlo conawait. - No capturar errores: un
awaitque falla sintry/catchdeja un error sin controlar. - Esperar en serie tareas independientes en lugar de usar
Promise.all. - Dejar un
setIntervalactivo sin cancelarlo. - Usar
innerHTMLcon datos de una API: son datos externos, usatextContent. - Dar por hecho que el orden de ejecución es el del código: lo asíncrono llega después.
📒 Apuntes para llevar
- JavaScript hace una cosa a la vez; lo asíncrono permite iniciar una tarea lenta y seguir, atendiendo el resultado cuando llegue.
setTimeoutejecuta una vez ysetIntervalrepetidamente; cancélalos conclearTimeout/clearInterval.- Una Promise está pendiente, cumplida o rechazada:
.then()recibe el valor,.catch()el error y.finally()siempre se ejecuta. async functiondevuelve una promesa;awaitespera el resultado sin congelar la página;try/catchcaptura los fallos.fetch(url)devuelve la respuesta: compruebarespuesta.oky usaawait respuesta.json().Promise.alllanza tareas independientes en paralelo;allSettledyracecubren otros casos.- Toda pantalla con datos remotos necesita estados de cargando, éxito, vacío y error.
- Los datos de internet son externos: muéstralos con
textContent.
9.Glosario
| Término | Significado |
|---|---|
| Asíncrono | Que no bloquea la ejecución mientras espera un resultado. |
| Promesa (Promise) | Objeto que representa un resultado futuro. |
async / await | Sintaxis para escribir promesas como código secuencial. |
fetch | Función que hace peticiones HTTP y devuelve una promesa. |
| API | Servicio que ofrece datos o funciones para ser usado por programas. |
| CORS | Mecanismo que restringe peticiones entre dominios distintos. |
| Callback | Función que se ejecuta cuando termina una tarea. |
Promise.all | Espera a que terminen varias promesas a la vez. |
🧠 Comprueba lo aprendido
Elige una respuesta en cada pregunta. Verás al instante si acertaste y por qué.
¿En qué orden se muestran? console.log(1); setTimeout(() => console.log(2), 0); console.log(3);
El callback del temporizador se ejecuta después de todo el código síncrono, incluso con 0 ms.
¿Qué devuelve una función async?
Una función async siempre devuelve una promesa.
fetch recibe un 404 del servidor. ¿Qué ocurre?
fetch solo se rechaza si falla la red; hay que comprobar ok.
Tienes 3 peticiones independientes. ¿Cómo tardas menos?
Promise.all las lanza juntas: tardas lo que tarde la más lenta.
Un setInterval que ya no necesitas, ¿qué requiere?
Sin cancelarlo, sigue ejecutándose indefinidamente.
Tu progreso se guarda en este navegador y se refleja en el índice del curso.
💡 🚀 ¡Ahora te toca!
La práctica fija lo aprendido. Pasa al ejercicio de esta lección.