Fetch API y async/await
Aprende la forma moderna de hacer peticiones HTTP y manejar código asíncrono de manera elegante con async/await.
1. Fetch API - La forma moderna
Fetch API es la forma moderna de hacer peticiones HTTP. Es mucho más simple y usa Promesas.
Ejemplo básico GET:
1// Con Fetch es mucho más simple2fetch('https://jsonplaceholder.typicode.com/users/1')3 .then(response => response.json())4 .then(datos => {5 console.log('Usuario:', datos);6 })7 .catch(error => {8 console.log('Error:', error);9 });Ventajas de Fetch:
- Sintaxis mucho más simple y limpia
- Usa Promesas (se puede encadenar con .then)
- Compatible con async/await
- Más fácil manejar errores
2. ¿Qué son las Promesas?
Una Promesa es un objeto que representa una operación que todavía no ha terminado, pero que terminará en el futuro.
Puede tener 3 estados:
Pending
Esperando (aún no terminó)
Fulfilled
Completada con éxito
Rejected
Falló (error)
1// Fetch devuelve una Promesa2const promesa = fetch('https://jsonplaceholder.typicode.com/users/1');3 4console.log(promesa); // Promise {<pending>}5 6// Usamos .then() para cuando se complete7promesa8 .then(response => response.json())9 .then(datos => {10 console.log('✅ Datos recibidos:', datos);11 })12 .catch(error => {13 console.log('❌ Error:', error);14 });3. async/await - Código más limpio
async/await es una forma más moderna de trabajar con Promesas. Hace que el código asíncrono se vea como código síncrono.
Sin async/await (con .then):
1fetch('https://jsonplaceholder.typicode.com/users/1')2 .then(response => response.json())3 .then(datos => {4 console.log('Usuario:', datos);5 })6 .catch(error => {7 console.log('Error:', error);8 });Con async/await (más limpio):
1async function obtenerUsuario() {2 try {3 const response = await fetch('https://jsonplaceholder.typicode.com/users/1');4 const datos = await response.json();5 console.log('Usuario:', datos);6 } catch (error) {7 console.log('Error:', error);8 }9}10 11obtenerUsuario();Reglas de async/await:
- •
asyncse pone antes de la función - •
awaitsolo funciona dentro de funcionesasync - •
awaitespera a que la Promesa se complete - • Usa
try/catchpara manejar errores
4. Enviar datos (POST)
Para enviar datos al servidor usamos el método POST con opciones adicionales:
1async function crearUsuario() {2 try {3 const nuevoUsuario = {4 name: 'Ana García',5 email: 'ana@example.com'6 };7 8 const response = await fetch('https://jsonplaceholder.typicode.com/users', {9 method: 'POST',10 headers: {11 'Content-Type': 'application/json'12 },13 body: JSON.stringify(nuevoUsuario)14 });15 16 const datos = await response.json();17 console.log('Usuario creado:', datos);18 } catch (error) {19 console.log('Error:', error);20 }21}22 23crearUsuario();5. Múltiples peticiones
Una después de otra (secuencial):
1async function obtenerDatos() {2 try {3 // Primero obtener el usuario4 const respuestaUsuario = await fetch('https://jsonplaceholder.typicode.com/users/1');5 const usuario = await respuestaUsuario.json();6 console.log('Usuario:', usuario.name);7 8 // Luego obtener sus posts9 const respuestaPosts = await fetch('https://jsonplaceholder.typicode.com/users/1/posts');10 const posts = await respuestaPosts.json();11 console.log('Posts:', posts.length);12 } catch (error) {13 console.log('Error:', error);14 }15}16 17obtenerDatos();Todas al mismo tiempo (paralelo):
1async function obtenerTodo() {2 try {3 // Lanzar todas las peticiones al mismo tiempo4 const [respuestaUsuario, respuestaPosts, respuestaTodos] = await Promise.all([5 fetch('https://jsonplaceholder.typicode.com/users/1'),6 fetch('https://jsonplaceholder.typicode.com/posts?userId=1'),7 fetch('https://jsonplaceholder.typicode.com/todos?userId=1')8 ]);9 10 const usuario = await respuestaUsuario.json();11 const posts = await respuestaPosts.json();12 const todos = await respuestaTodos.json();13 14 console.log('Usuario:', usuario.name);15 console.log('Posts:', posts.length);16 console.log('Todos:', todos.length);17 } catch (error) {18 console.log('Error:', error);19 }20}21 22obtenerTodo(); Tip: Usa Promise.all() cuando las peticiones no dependan una de otra. Será mucho más rápido.
6. XMLHttpRequest vs Fetch vs async/await
XMLHttpRequest
- • Muy verboso
- • Callbacks anidados
- • Difícil de leer
- • Forma antigua
Fetch + .then
- • Más simple
- • Usa Promesas
- • Puede anidar .then
- • Mejor que XHR
async/await
- • Muy limpio
- • Fácil de leer
- • Código lineal
- • La mejor opción
Ejercicio práctico
Galería de Usuarios con Fetch y async/await
Vas a crear una aplicación web que muestre información de usuarios y sus publicaciones. Practicarás async/await para obtener datos de una API y manipulación del DOM para crear la interfaz dinámica.
1 Crear la estructura HTML
Crea un archivo index.html con esta estructura básica:
- ▸ Un título h1 que diga "Galería de Usuarios"
- ▸ Un botón con id
cargar-btny texto "Cargar Usuarios" - ▸ Un div contenedor con id
usuarios-containerdonde aparecerán las tarjetas - ▸ Un tag script que importe el archivo
app.jsantes del cierre del body
Consejo: Puedes usar Bootstrap para estilizar las tarjetas fácilmente.
Agrega el CDN de Bootstrap en el head de tu HTML y usa clases como card, btn btn-primary, container, etc.
2 Crear la función para obtener datos (async/await)
En app.js, crea una función async llamada cargarUsuarios():
🌐 API recomendada: DummyJSON
Una API gratuita y confiable para pruebas y prototipos
Obtener UN usuario específico:
https://dummyjson.com/users/1 → Datos en: data.firstName, data.lastName, etc.
Obtener MÚLTIPLES usuarios (con límite):
https://dummyjson.com/users?limit=3 → Datos en: data.users (es un array)
⚠️ Cambia limit=3 por el número que necesites (ej: limit=15 para 15 usuarios)
Posts de un usuario específico:
https://dummyjson.com/posts/user/1 → Datos en: data.posts (es un array)
⚠️ Reemplaza el 1 por el ID del usuario
💡 Ejemplo rápido: Obtener un usuario y mostrar su nombre
1async function ejemploRapido() {2 const response = await fetch('https://dummyjson.com/users/1');3 const data = await response.json();4 5 // Los datos del usuario están directamente en 'data'6 const nombreCompleto = data.firstName + ' ' + data.lastName;7 8 // Crear y agregar un h3 al DOM9 const titulo = document.createElement('h3');10 titulo.textContent = nombreCompleto;11 document.body.appendChild(titulo);12}2.1 Obtener usuarios
- • Usa
await fetch()para obtener datos de:
https://dummyjson.com/users?limit=3 - • Convierte la respuesta a JSON con
await response.json() - • Los datos vienen en
data.users(DummyJSON usa esta estructura)
2.2 Obtener posts de cada usuario
- • Para cada usuario, obtén sus posts de:
https://dummyjson.com/posts/user/1
(reemplaza el 1 con el id del usuario) - • Usa
Promise.all()para hacer todas las peticiones en paralelo - • Los posts vienen en
data.posts
2.3 Manejo de errores
- • Envuelve todo el código en un bloque
try/catch - • Si hay error, muestra un mensaje en consola con
console.error()
⚠️ API alternativa (si DummyJSON no funciona):
Puedes usar Dog API para mostrar razas de perros e imágenes:
- • Lista de razas:
https://dog.ceo/api/breeds/list/all - • Imagen aleatoria de una raza:
https://dog.ceo/api/breed/shiba/images/random - • Múltiples imágenes:
https://dog.ceo/api/breed/labrador/images/random/3
(Reemplaza "shiba" o "labrador" con cualquier raza)
3 Crear las tarjetas dinámicamente (Interfaz)
Dentro de la función cargarUsuarios(), después de obtener los datos:
3.1 Limpiar el contenedor
- • Obtén el contenedor con
document.getElementById('usuarios-container') - • Limpia su contenido con
container.innerHTML = ''
3.2 Crear una tarjeta para cada usuario
- • Recorre el array de usuarios con
forEach - • Para cada usuario, crea un
divcondocument.createElement('div') - • Agrega una clase CSS a la tarjeta (ejemplo:
'usuario-card')
3.3 Agregar contenido a cada tarjeta
Usa innerHTML para agregar el HTML de la tarjeta. Debe mostrar:
- ▸ Nombre del usuario en un h2 o h3 (usa
usuario.firstNameyusuario.lastName) - ▸ Email en un párrafo (
usuario.email) - ▸ Cantidad de posts (usa
posts.length) - ▸ Títulos de los primeros 3 posts en divs o en una lista (usa
posts.slice(0, 3)ypost.title)
3.4 Agregar la tarjeta al contenedor
- • Usa
container.appendChild(card)para agregar cada tarjeta
4 Conectar el botón con la función
- • Al final de
app.js, obtén el botón condocument.getElementById('cargar-btn') - • Agrega un event listener con
addEventListener('click', cargarUsuarios) - • ¡Prueba tu aplicación! Haz clic en el botón y deberían aparecer las tarjetas
Tip: Usa concatenación de strings o template literals para construir el HTML dentro de innerHTML
Extra: Puedes agregar un mensaje de "Cargando..." mientras se obtienen los datos