diff --git a/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/README.md b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/README.md new file mode 100644 index 0000000..759d4ee --- /dev/null +++ b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/README.md @@ -0,0 +1,318 @@ +# 📚 Ejercicios de Async/Await - JSONPlaceholder API + +## 🎯 Objetivo + +Aprender a usar **async/await** para hacer solicitudes a una API de forma asincrónica, entendiendo cómo el código espera respuestas sin bloquear la ejecución. + +--- + +## 📁 Archivos Incluidos + +### 1. **ejercicio1_obtenerTodos.js** 📋 + +**Nivel:** Principiante +**Concepto Principal:** Uso básico de async/await + +Este es el más didáctico. Obtiene una lista de tareas (todos) de la API. + +**Lo que aprenderás:** + +- Cómo crear una función `async` +- Cómo usar `await` para esperar respuestas +- Validación de respuestas con `.ok` +- Conversión de respuesta JSON +- Manejo de errores con `try/catch` +- Iteración y display de datos + +```javascript +async function obtenerTareas() { + try { + const respuesta = await fetch("https://jsonplaceholder.typicode.com/todos"); + const datos = await respuesta.json(); + console.log(datos); + } catch (error) { + console.error("Error:", error); + } +} +``` + +--- + +### 2. **ejercicio2_obtenerAlbumes.js** 📀 + +**Nivel:** Principiante +**Concepto Principal:** Reutilización del patrón + +Idéntico al anterior pero con otro endpoint (`/albums`). Muestra que el patrón funciona con cualquier recurso. + +--- + +### 3. **ejercicio3_funcion_generica.js** 🔧 + +**Nivel:** Intermedio +**Concepto Principal:** Abstracción + +Una única función que puede obtener cualquier endpoint. Es más eficiente que copiar código. + +```javascript +async function obtenerDatos(endpoint) { + const url = `https://jsonplaceholder.typicode.com${endpoint}`; + const respuesta = await fetch(url); + const datos = await respuesta.json(); + return datos; +} + +obtenerDatos("/users"); // Obtiene usuarios +obtenerDatos("/posts"); // Obtiene posts +obtenerDatos("/albums"); // Obtiene álbumes +``` + +--- + +### 4. **ejercicio4_obtenerUsuarios.js** 👥 +**Nivel:** Principiante +**Concepto Principal:** Obtener usuarios específicos + +Similar a los ejercicios 1 y 2, pero obtiene usuarios con información detallada (nombre, email, teléfono, etc.). + +--- + +### 5. **index.html** 🌐 + +**Mejor para:** Práctica interactiva en el navegador + +**Características:** + +- Interfaz visual con botones +- Puedes ver resultados en tiempo real +- Manejo de errores visible +- 4 ejemplos diferentes (Tareas, Álbumes, Usuarios, Posts) +- Limite de resultados para no saturar la pantalla + +**Cómo usarlo:** + +1. Abre el archivo en tu navegador +2. Hace clic en cualquier botón +3. Los datos aparecerán en la pantalla + +--- + +### 6. **guia_educativa.js** 📖 + +**Mejor para:** Lectura y comprensión de conceptos + +Contiene: + +- Explicación de qué es `async` +- Explicación de qué es `await` +- Ejemplos de manejo de errores +- Comparación: async/await vs Promises vs Callbacks +- Ejemplo de múltiples solicitudes +- Ejemplo práctico completo + +--- + +## 🚀 Cómo Usar + +### Opción 1: Visual en Navegador (RECOMENDADO para aprender) + +```bash +# Abre index.html en tu navegador +# Haz clic en los botones y ve cómo funciona en tiempo real +``` + +### Opción 2: En Node.js (para archivos .js) + +```bash +# Desde la terminal +node ejercicio1_obtenerTodos.js +node ejercicio2_obtenerAlbumes.js +node ejercicio3_funcion_generica.js +``` + +### Opción 3: En la Consola del Navegador + +```javascript +// Abre la consola (F12) en el navegador con cualquier página +// Copia y pega el código de cualquier archivo .js +// Presiona Enter para ejecutar +``` + +--- + +## 🔗 Endpoints Disponibles + +La API JSONPlaceholder proporciona estos recursos: + +| Endpoint | Descripción | Cantidad | +| ----------- | ------------------ | -------- | +| `/users` | Usuarios de prueba | 10 | +| `/posts` | Artículos/Posts | 100 | +| `/comments` | Comentarios | 500 | +| `/albums` | Álbumes de fotos | 100 | +| `/photos` | Fotos | 5000 | +| `/todos` | Tareas | 200 | + +**Ejemplo de URL completa:** + +- `https://jsonplaceholder.typicode.com/users` +- `https://jsonplaceholder.typicode.com/posts?userId=1` (posts del usuario 1) +- `https://jsonplaceholder.typicode.com/comments?postId=1` (comentarios del post 1) + +--- + +## 📝 Conceptos Clave + +### async + +```javascript +async function miFunc() { + // Esta función puede contener 'await' +} +``` + +- Transforma una función normal en asincrónica +- Permite usar `await` dentro de ella + +### await + +```javascript +const datos = await fetch(url); +``` + +- Pausa la ejecución en esa línea +- Espera a que la Promesa se resuelva +- SOLO funciona en funciones `async` + +### try/catch + +```javascript +try { + // Código que puede fallar + const respuesta = await fetch(url); +} catch (error) { + // Se ejecuta si hay error + console.error(error); +} +``` + +- Captura errores de red, API caída, etc. + +--- + +## ❌ Errores Comunes + +### Error 1: Usar `await` sin `async` + +```javascript +❌ INCORRECTO: +function obtener() { + const datos = await fetch(url); // Error! +} + +✅ CORRECTO: +async function obtener() { + const datos = await fetch(url); // OK +} +``` + +### Error 2: Olvidar `await` + +```javascript +❌ INCORRECTO: +async function obtener() { + const datos = fetch(url); // Retorna Promesa, no datos + console.log(datos); // [Promise] +} + +✅ CORRECTO: +async function obtener() { + const datos = await fetch(url); + console.log(datos); // Response object +} +``` + +### Error 3: No manejar errores + +```javascript +❌ ARRIESGADO: +async function obtener() { + const respuesta = await fetch(url); + const datos = await respuesta.json(); + // Si la API está caída, se detiene aquí +} + +✅ SEGURO: +async function obtener() { + try { + const respuesta = await fetch(url); + const datos = await respuesta.json(); + } catch (error) { + console.error("Error:", error); + } +} +``` + +--- + +## 🧠 Flujo Paso a Paso + +Cuando ejecutas este código: + +```javascript +async function obtenerDatos() { + const respuesta = await fetch("https://api.ejemplo.com/datos"); + const datos = await respuesta.json(); + console.log(datos); +} + +console.log("1. Antes"); +obtenerDatos(); +console.log("2. Después"); +``` + +**La salida será:** + +``` +1. Antes +2. Después +[datos de la API aparecen aquí] +``` + +¿Por qué? Porque `obtenerDatos()` es asincrónica, JavaScript continúa con el resto del código sin esperar a que termine. + +--- + +## 💡 Consejos + +1. **Empieza con `index.html`** - Es visual y fácil de entender +2. **Lee los comentarios** - Cada línea tiene explicación +3. **Experimenta** - Cambia los endpoints, prueba diferentes datos +4. **Abre la consola (F12)** - Verás logs detallados de qué sucede +5. **Compara ejercicios** - Nota las similitudes entre ejercicio1, 2 y 3 + +--- + +## 🎓 Próximos Pasos + +Una vez entiendas esto, puedes aprender: + +- ✅ Promise.all() - Múltiples solicitudes paralelas +- ✅ Error handling avanzado +- ✅ Timeout en solicitudes +- ✅ Retry automático +- ✅ Cacheo de datos +- ✅ Uso de bibliotecas como axios o fetch mejorado + +--- + +## 📚 Recursos Adicionales + +- [MDN - async/await](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/async_function) +- [MDN - Promise](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Promise) +- [JSONPlaceholder - Documentación](https://jsonplaceholder.typicode.com/) +- [Fetch API](https://developer.mozilla.org/es/docs/Web/API/Fetch_API) + +--- + +**¡Buena suerte aprendiendo! 🚀** diff --git a/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/cheat_sheet.js b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/cheat_sheet.js new file mode 100644 index 0000000..c2a4f27 --- /dev/null +++ b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/cheat_sheet.js @@ -0,0 +1,301 @@ +/** + * 🔖 CHEAT SHEET: async/await + * + * Referencia rápida de la sintaxis y patrones más comunes + */ + +// ═══════════════════════════════════════════════════════════════════════════ +// 🟢 PATRÓN BÁSICO +// ═══════════════════════════════════════════════════════════════════════════ + +async function basico() { + try { + const respuesta = await fetch(url); + const datos = await respuesta.json(); + return datos; + } catch (error) { + console.error(error); + } +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 🟢 VALIDAR QUE LA RESPUESTA SEA EXITOSA +// ═══════════════════════════════════════════════════════════════════════════ + +async function conValidacion() { + const respuesta = await fetch(url); + + if (!respuesta.ok) { + throw new Error(`HTTP Error: ${respuesta.status}`); + } + + const datos = await respuesta.json(); + return datos; +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 🟢 MÚLTIPLES SOLICITUDES - UNA POR UNA +// ═══════════════════════════════════════════════════════════════════════════ + +async function secuencial() { + const resp1 = await fetch(url1); + const datos1 = await resp1.json(); + + const resp2 = await fetch(url2); + const datos2 = await resp2.json(); + + return { datos1, datos2 }; +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 🟢 MÚLTIPLES SOLICITUDES - TODAS AL MISMO TIEMPO (MÁS RÁPIDO) +// ═══════════════════════════════════════════════════════════════════════════ + +async function paralelo() { + const [datos1, datos2, datos3] = await Promise.all([ + fetch(url1).then(r => r.json()), + fetch(url2).then(r => r.json()), + fetch(url3).then(r => r.json()) + ]); + + return { datos1, datos2, datos3 }; +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 🟢 CON PARÁMETROS +// ═══════════════════════════════════════════════════════════════════════════ + +async function conParametros(userId, postId) { + const url = `https://api.ejemplo.com/users/${userId}/posts/${postId}`; + const respuesta = await fetch(url); + const datos = await respuesta.json(); + return datos; +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 🟢 JSON PLACEHOLDER EJEMPLOS RÁPIDOS +// ═══════════════════════════════════════════════════════════════════════════ + +// Obtener un usuario +async function getUser(id) { + const resp = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`); + return await resp.json(); +} + +// Obtener posts de un usuario +async function getUserPosts(userId) { + const resp = await fetch(`https://jsonplaceholder.typicode.com/posts?userId=${userId}`); + return await resp.json(); +} + +// Obtener comentarios de un post +async function getPostComments(postId) { + const resp = await fetch(`https://jsonplaceholder.typicode.com/posts/${postId}/comments`); + return await resp.json(); +} + +// Obtener fotos de un álbum +async function getAlbumPhotos(albumId) { + const resp = await fetch(`https://jsonplaceholder.typicode.com/albums/${albumId}/photos`); + return await resp.json(); +} + +// Obtener todas las tareas completadas +async function getCompletedTodos() { + const resp = await fetch("https://jsonplaceholder.typicode.com/todos?completed=true"); + return await resp.json(); +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 🟢 CON HEADERS PERSONALIZADOS +// ═══════════════════════════════════════════════════════════════════════════ + +async function conHeaders() { + const respuesta = await fetch(url, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer token123' + } + }); + + return await respuesta.json(); +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 🟢 POST - ENVIAR DATOS +// ═══════════════════════════════════════════════════════════════════════════ + +async function enviarDatos(datos) { + const respuesta = await fetch('https://jsonplaceholder.typicode.com/posts', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(datos) + }); + + return await respuesta.json(); +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 🟢 MANEJO AVANZADO DE ERRORES +// ═══════════════════════════════════════════════════════════════════════════ + +async function conErrorAvanzado() { + try { + const respuesta = await fetch(url); + + if (!respuesta.ok) { + throw new Error(`HTTP ${respuesta.status}: ${respuesta.statusText}`); + } + + const datos = await respuesta.json(); + return datos; + + } catch (error) { + if (error instanceof TypeError) { + console.error("Error de red:", error.message); + } else if (error instanceof SyntaxError) { + console.error("JSON inválido:", error.message); + } else { + console.error("Otro error:", error.message); + } + + return null; + } +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 🟢 CON TIMEOUT (Máximo tiempo de espera) +// ═══════════════════════════════════════════════════════════════════════════ + +async function conTimeout(url, timeoutMs = 5000) { + const controller = new AbortController(); + const timeout = setTimeout(() => controller.abort(), timeoutMs); + + try { + const respuesta = await fetch(url, { signal: controller.signal }); + return await respuesta.json(); + } finally { + clearTimeout(timeout); + } +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 🟢 REINTENTOS AUTOMÁTICOS +// ═══════════════════════════════════════════════════════════════════════════ + +async function conReintentos(url, intentosMax = 3) { + for (let intento = 1; intento <= intentosMax; intento++) { + try { + const respuesta = await fetch(url); + if (respuesta.ok) { + return await respuesta.json(); + } + } catch (error) { + console.log(`Intento ${intento} falló`); + if (intento === intentosMax) throw error; + } + } +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 🟢 CARGAR MÚLTIPLES DATOS DE UN USUARIO +// ═══════════════════════════════════════════════════════════════════════════ + +async function getUserComplete(userId) { + const [usuario, posts, albums, todos] = await Promise.all([ + fetch(`https://jsonplaceholder.typicode.com/users/${userId}`).then(r => r.json()), + fetch(`https://jsonplaceholder.typicode.com/posts?userId=${userId}`).then(r => r.json()), + fetch(`https://jsonplaceholder.typicode.com/albums?userId=${userId}`).then(r => r.json()), + fetch(`https://jsonplaceholder.typicode.com/todos?userId=${userId}`).then(r => r.json()) + ]); + + return { + usuario, + postCount: posts.length, + albumCount: albums.length, + todoCount: todos.length, + completedTodos: todos.filter(t => t.completed).length + }; +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 🟢 CON INDICADOR DE CARGA +// ═══════════════════════════════════════════════════════════════════════════ + +async function conIndicador(url) { + console.log("⏳ Cargando..."); + + try { + const respuesta = await fetch(url); + const datos = await respuesta.json(); + console.log("✓ Completado"); + return datos; + } catch (error) { + console.log("✗ Error"); + throw error; + } +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// TABLA DE REFERENCIA RÁPIDA +// ═══════════════════════════════════════════════════════════════════════════ + +/* +SINTAXIS BÁSICA: + async function nombre() { + try { + const respuesta = await fetch(url); + const datos = await respuesta.json(); + return datos; + } catch (error) { + console.error(error); + } + } + +MÉTODOS HTTP: + GET → Obtener datos + POST → Crear datos + PUT → Actualizar datos + DELETE → Eliminar datos + PATCH → Actualización parcial + +STATUS CODES COMUNES: + 200 OK - Solicitud exitosa + 201 Created - Recurso creado + 400 Bad Request - Error en la solicitud + 401 Unauthorized - Sin autenticación + 404 Not Found - Recurso no encontrado + 500 Server Error - Error del servidor + +RESPONSE METHODS: + .json() → Convierte a JSON + .text() → Convierte a texto + .blob() → Convierte a blob (para archivos) + .arrayBuffer() → Convierte a array buffer + +VALIDACIÓN: + respuesta.ok → true si status 200-299 + respuesta.status → Número del código HTTP + respuesta.headers → Headers de la respuesta + +ERRORES COMUNES: + Error de red → catch { } + JSON inválido → SyntaxError + Endpoint no existe → respuesta.status 404 +*/ diff --git a/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/ejercicio1_obtenerTodos.js b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/ejercicio1_obtenerTodos.js new file mode 100644 index 0000000..c87d294 --- /dev/null +++ b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/ejercicio1_obtenerTodos.js @@ -0,0 +1,56 @@ +/** + * EJERCICIO 1: Obtener Tareas (Todos) - Versión Educativa + * + * Este ejercicio usa async/await para hacer una solicitud HTTP + * a la API JSONPlaceholder y obtener una lista de tareas. + * + * ¿QUÉ APRENDEREMOS? + * - Cómo usar async para crear funciones asincrónicas + * - Cómo usar await para esperar respuestas + * - Manejo de errores con try/catch + * - Cómo parsear JSON desde una API + */ + +// Paso 1: Definir una función asincrónica +// 'async' le indica a JavaScript que esta función puede tener operaciones que tarden tiempo +async function obtenerTareas() { + try { + // Paso 2: Hacer una solicitud HTTP + // fetch() pide datos a una URL + // await espera a que la respuesta llegue (puede tardar tiempo en internet) + const respuesta = await fetch("https://jsonplaceholder.typicode.com/todos"); + + // Paso 3: Verificar si la respuesta fue exitosa + // respuesta.ok es true si el servidor respondió correctamente (código 200) + if (!respuesta.ok) { + throw new Error(`Error HTTP: ${respuesta.status}`); + } + + // Paso 4: Convertir la respuesta a formato JSON + // respuesta.json() convierte el texto en objetos JavaScript + // await espera a que termine la conversión + const datos = await respuesta.json(); + + // Paso 5: Mostrar los datos en la consola + console.log("✓ Tareas obtenidas exitosamente:"); + console.log(`Total de tareas: ${datos.length}`); + + // Mostrar solo las primeras 5 tareas para no saturar la consola + console.log("\nPrimeras 5 tareas:"); + datos.slice(0, 5).forEach((tarea, indice) => { + console.log(`${indice + 1}. ${tarea.title}`); + console.log(` Estado: ${tarea.completed ? "✓ Completada" : "✗ Pendiente"}`); + }); + + return datos; // Retornar los datos para usarlos si es necesario + + } catch (error) { + // Paso 6: Si algo falla, capturamos el error aquí + // Esto puede ocurrir si no hay conexión a internet o la API está caída + console.error("✗ Error al obtener las tareas:", error.message); + } +} + +// Paso 7: Ejecutar la función +// Llamamos a la función para que comience la solicitud +obtenerTareas(); diff --git a/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/ejercicio2_obtenerAlbumes.js b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/ejercicio2_obtenerAlbumes.js new file mode 100644 index 0000000..980019f --- /dev/null +++ b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/ejercicio2_obtenerAlbumes.js @@ -0,0 +1,37 @@ +/** + * EJERCICIO 2: Obtener Álbumes - Versión Mejorada + * + * Este ejercicio es una variación que obtiene álbumes en lugar de tareas. + * Muestra cómo reutilizar el patrón async/await para diferentes recursos. + */ + +async function obtenerAlbumes() { + try { + // Solicitud al endpoint /albums + const respuesta = await fetch("https://jsonplaceholder.typicode.com/albums"); + + if (!respuesta.ok) { + throw new Error(`Error HTTP: ${respuesta.status}`); + } + + const datos = await respuesta.json(); + + console.log("📀 ÁLBUMES OBTENIDOS:\n"); + console.log(`Total de álbumes: ${datos.length}\n`); + + // Mostrar información de los primeros 3 álbumes + console.log("Primeros 3 álbumes:"); + datos.slice(0, 3).forEach((album) => { + console.log(`\nID: ${album.id}`); + console.log(`Título: ${album.title}`); + console.log(`Usuario ID: ${album.userId}`); + }); + + return datos; + + } catch (error) { + console.error("Error al obtener los álbumes:", error.message); + } +} + +obtenerAlbumes(); diff --git a/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/ejercicio3_funcion_generica.js b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/ejercicio3_funcion_generica.js new file mode 100644 index 0000000..8c66b0a --- /dev/null +++ b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/ejercicio3_funcion_generica.js @@ -0,0 +1,51 @@ +/** + * EJERCICIO 3: Función Genérica Reutilizable + * + * Este es un paso adelante. En lugar de crear una función para cada endpoint, + * creamos una función genérica que funciona con cualquier recurso. + */ + +// Esta función puede usarse para CUALQUIER endpoint de JSONPlaceholder +async function obtenerDatos(endpoint) { + try { + const url = `https://jsonplaceholder.typicode.com${endpoint}`; + console.log(`🔄 Buscando datos en: ${url}\n`); + + const respuesta = await fetch(url); + + if (!respuesta.ok) { + throw new Error(`Error HTTP: ${respuesta.status}`); + } + + const datos = await respuesta.json(); + + console.log(`✓ Se obtuvieron ${datos.length} registros\n`); + + return datos; + + } catch (error) { + console.error(`✗ Error: ${error.message}`); + return null; + } +} + +// EJEMPLOS DE USO: +// Descomenta la línea que quieras ejecutar + +// Obtener 10 usuarios +// obtenerDatos("/users"); + +// Obtener 200 tareas +// obtenerDatos("/todos"); + +// Obtener 100 posts +// obtenerDatos("/posts"); + +// Obtener 100 álbumes +// obtenerDatos("/albums"); + +// Obtener 500 comentarios +// obtenerDatos("/comments"); + +// Obtener 5000 fotos +obtenerDatos("/photos"); diff --git a/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/guia_educativa.js b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/guia_educativa.js new file mode 100644 index 0000000..4f61255 --- /dev/null +++ b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/guia_educativa.js @@ -0,0 +1,228 @@ +/** + * 📚 GUÍA EDUCATIVA: async/await + * + * CONCEPTOS CLAVE + */ + +// ═══════════════════════════════════════════════════════════════════════════ +// 1. ¿QUÉ ES ASYNC? +// ═══════════════════════════════════════════════════════════════════════════ + +// Palabra clave que convierte una función en asincrónica +// Permite usar 'await' dentro de ella + +// SIN ASYNC (función normal): +function obtenerDatos1() { + return "datos"; +} + +// CON ASYNC (función asincrónica): +async function obtenerDatos2() { + return "datos"; +} + +// La diferencia: async permite operaciones que tardan tiempo sin bloquear + + +// ═══════════════════════════════════════════════════════════════════════════ +// 2. ¿QUÉ ES AWAIT? +// ═══════════════════════════════════════════════════════════════════════════ + +// Pausa en una línea hasta que la Promesa se resuelva +// SOLO se puede usar dentro de funciones async + +async function ejemplo() { + // Espera a que fetch() retorne una respuesta + const respuesta = await fetch("https://api.ejemplo.com/datos"); + + // Una vez que tenemos respuesta, continuamos + const datos = await respuesta.json(); + + // Ahora 'datos' tiene la información + console.log(datos); +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 3. TRY/CATCH - MANEJO DE ERRORES +// ═══════════════════════════════════════════════════════════════════════════ + +async function obtenerUserSafe(userId) { + try { + // Aquí pueden ocurrir errores + const respuesta = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`); + + if (!respuesta.ok) { + throw new Error(`Usuario no encontrado: ${respuesta.status}`); + } + + const usuario = await respuesta.json(); + return usuario; + + } catch (error) { + // Si algo falla, capturamos aquí + console.error("Error:", error.message); + return null; + } +} + +// ERRORES COMUNES: +// - Sin conexión a internet +// - La API está caída +// - La URL es incorrecta +// - El recurso no existe + + +// ═══════════════════════════════════════════════════════════════════════════ +// 4. FLUJO PASO A PASO +// ═══════════════════════════════════════════════════════════════════════════ + +async function flujoCompleto() { + console.log("1️⃣ Inicio de la función"); + + // Paso 1: Hacer solicitud + console.log("2️⃣ Haciendo solicitud a la API..."); + const respuesta = await fetch("https://jsonplaceholder.typicode.com/users/1"); + console.log("3️⃣ Respuesta recibida del servidor"); + + // Paso 2: Verificar si fue exitosa + if (!respuesta.ok) { + console.log("4️⃣ Error! El servidor respondió con código:", respuesta.status); + return; + } + + // Paso 3: Convertir a JSON + console.log("4️⃣ Convirtiendo respuesta a JSON..."); + const datos = await respuesta.json(); + console.log("5️⃣ ¡Datos listos!"); + + // Paso 4: Usar los datos + console.log("6️⃣ Mostrando datos:"); + console.log(`Nombre: ${datos.name}`); + console.log(`Email: ${datos.email}`); + console.log(`Teléfono: ${datos.phone}`); +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 5. ENDPOINTS DISPONIBLES EN JSONPLACEHOLDER +// ═══════════════════════════════════════════════════════════════════════════ + +const ENDPOINTS = { + users: "https://jsonplaceholder.typicode.com/users", // 10 usuarios + posts: "https://jsonplaceholder.typicode.com/posts", // 100 posts + comments: "https://jsonplaceholder.typicode.com/comments", // 500 comentarios + albums: "https://jsonplaceholder.typicode.com/albums", // 100 álbumes + photos: "https://jsonplaceholder.typicode.com/photos", // 5000 fotos + todos: "https://jsonplaceholder.typicode.com/todos" // 200 tareas +}; + + +// ═══════════════════════════════════════════════════════════════════════════ +// 6. COMPARACIÓN: ASYNC/AWAIT vs PROMISES vs CALLBACKS +// ═══════════════════════════════════════════════════════════════════════════ + +// FORMA ANTIGUA (Callbacks): +function obtenerDatosCallback(url, callback) { + fetch(url) + .then(respuesta => respuesta.json()) + .then(datos => callback(datos)) + .catch(error => console.error(error)); +} + +// FORMA INTERMEDIA (Promises): +function obtenerDatosPromise(url) { + return fetch(url) + .then(respuesta => respuesta.json()) + .catch(error => console.error(error)); +} + +// FORMA MODERNA (async/await): ✨ +async function obtenerDatosAsync(url) { + try { + const respuesta = await fetch(url); + const datos = await respuesta.json(); + return datos; + } catch (error) { + console.error(error); + } +} + +// async/await es más legible y fácil de entender + + +// ═══════════════════════════════════════════════════════════════════════════ +// 7. ESPERAR MÚLTIPLES SOLICITUDES +// ═══════════════════════════════════════════════════════════════════════════ + +// Esperar UNA por UNA (lento): +async function obtenerDatosSeparado() { + const usuarios = await fetch("https://jsonplaceholder.typicode.com/users").then(r => r.json()); + const posts = await fetch("https://jsonplaceholder.typicode.com/posts?userId=1").then(r => r.json()); + const albums = await fetch("https://jsonplaceholder.typicode.com/albums?userId=1").then(r => r.json()); + return { usuarios, posts, albums }; +} + +// Esperar TODAS AL MISMO TIEMPO (rápido): +async function obtenerDatosParalelo() { + const [usuarios, posts, albums] = await Promise.all([ + fetch("https://jsonplaceholder.typicode.com/users").then(r => r.json()), + fetch("https://jsonplaceholder.typicode.com/posts?userId=1").then(r => r.json()), + fetch("https://jsonplaceholder.typicode.com/albums?userId=1").then(r => r.json()) + ]); + return { usuarios, posts, albums }; +} + + +// ═══════════════════════════════════════════════════════════════════════════ +// 8. EJEMPLO PRÁCTICO COMPLETO +// ═══════════════════════════════════════════════════════════════════════════ + +async function mostrarInformacionUsuario(userId) { + try { + // 1. Obtener el usuario + const respuestaUsuario = await fetch( + `https://jsonplaceholder.typicode.com/users/${userId}` + ); + + if (!respuestaUsuario.ok) { + throw new Error("Usuario no encontrado"); + } + + const usuario = await respuestaUsuario.json(); + + // 2. Obtener sus posts + const respuestaPosts = await fetch( + `https://jsonplaceholder.typicode.com/posts?userId=${userId}` + ); + const posts = await respuestaPosts.json(); + + // 3. Obtener sus álbumes + const respuestaAlbumes = await fetch( + `https://jsonplaceholder.typicode.com/albums?userId=${userId}` + ); + const albumes = await respuestaAlbumes.json(); + + // 4. Mostrar información + console.log("═══════════════════════════════════"); + console.log(`Usuario: ${usuario.name}`); + console.log(`Email: ${usuario.email}`); + console.log(`Posts: ${posts.length}`); + console.log(`Álbumes: ${albumes.length}`); + console.log("═══════════════════════════════════"); + + } catch (error) { + console.error("Error:", error.message); + } +} + +// Uso: +// mostrarInformacionUsuario(1); + + +// ═══════════════════════════════════════════════════════════════════════════ +// ¡AHORA PRUEBA! +// ═══════════════════════════════════════════════════════════════════════════ + +console.log("Abre el archivo index.html en tu navegador para ver los ejercicios interactivos"); +console.log("O descomenta alguna función y ejecútala en la consola"); diff --git a/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/index.html b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/index.html new file mode 100644 index 0000000..19e0185 --- /dev/null +++ b/estudiantes/g3-2026/jose-mejia/ejercicioAbril06/asyncAwait/index.html @@ -0,0 +1,299 @@ + + +
+ + +JSONPlaceholder API - Aprende sobre operaciones asincrónicas
+ +