Programación Asíncrona
## Objetivos de Aprendizaje
- Entender callbacks y sus problemas
- Dominar Promesas
- Usar async/await
- Manejar errores asíncronos
## Programación Síncrona vs Asíncrona
### Síncrono
```javascript
console.log("Primero");
console.log("Segundo");
console.log("Tercero");
// Orden garantizado: 1, 2, 3
```
### Asíncrono
```javascript
console.log("Primero");
setTimeout(() => {
console.log("Tercero (después de 1s)");
}, 1000);
console.log("Segundo");
```
## Callbacks
### Función Callback
```javascript
function procesar(datos, callback) {
callback(datos * 2);
}
procesar(5, resultado => {
console.log(resultado); // 10
});
```
### Callback Hell (Evitar)
```javascript
getUser(userId, (user) => {
getPosts(user.id, (posts) => {
getComments(posts[0].id, (comments) => {
console.log(comments);
});
});
});
```
## Promesas
### Crear una Promesa
```javascript
const miPromesa = new Promise((resolve, reject) => {
const exito = true;
if (exito) {
resolve("¡Operación exitosa!");
} else {
reject("Algo salió mal");
}
});
```
### Estados de Promesa
| Estado | Descripción |
|--------|-------------|
| pending | Inicial, ni cumplida ni rechazada |
| fulfilled | Operación exitosa |
| rejected | Operación fallida |
### then, catch, finally
```javascript
miPromesa
.then(resultado => {
console.log(resultado); // "¡Operación exitosa!"
})
.catch(error => {
console.error(error); // "Algo salió mal"
})
.finally(() => {
console.log("Siempre se ejecuta");
});
```
### Encadenar Promesas
```javascript
fetch(url)
.then(response => response.json())
.then(data => procesar(data))
.then(resultado => mostrar(resultado))
.catch(error => console.error(error));
```
## async/await
### Función async
```javascript
async function obtenerDatos() {
return "datos";
}
obtenerDatos().then(console.log); // "datos"
```
### await
```javascript
async function obtenerUsuario(id) {
try {
const respuesta = await fetch(`/api/users/${id}`);
const usuario = await respuesta.json();
return usuario;
} catch (error) {
console.error("Error:", error);
}
}
```
### try...catch con async/await
```javascript
async function procesar() {
try {
const resultado = await operacionAsincrona();
console.log(resultado);
} catch (error) {
console.error("Error:", error);
}
}
```
## Promise.all
### Ejecutar Múltiples Promesas
```javascript
async function obtenerDatos() {
const [usuarios, posts] = await Promise.all([
fetch("/api/users").then(r => r.json()),
fetch("/api/posts").then(r => r.json())
]);
return { usuarios, posts };
}
```
### Promise.race
```javascript
Promise.race([
fetch("/api/datos-rapidos"),
new Promise((_, reject) =>
setTimeout(() => reject(new Error("Tiempo agotado")), 3000)
)
]);
```
## setTimeout y setInterval
### setTimeout
```javascript
console.log("Inicio");
setTimeout(() => {
console.log("Ejecutado después de 1 segundo");
}, 1000);
console.log("Fin");
```
### setInterval
```javascript
let segundos = 0;
const intervalo = setInterval(() => {
segundos++;
console.log(`Han pasado ${segundos} segundos`);
if (segundos === 5) {
clearInterval(intervalo);
console.log("Intervalo detenido");
}
}, 1000);
```
## fetch API
### Solicitud Básica
```javascript
fetch("https://api.ejemplo.com/datos")
.then(respuesta => respuesta.json())
.then(datos => console.log(datos))
.catch(error => console.error("Error:", error));
```
### POST Request
```javascript
fetch("/api/usuarios", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
nombre: "Juan",
email: "juan@ejemplo.com"
})
})
.then(respuesta => respuesta.json())
.then(datos => console.log(datos))
.catch(error => console.error("Error:", error));
```
### Con async/await
```javascript
async function crearUsuario(datos) {
try {
const respuesta = await fetch("/api/usuarios", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(datos)
});
if (!respuesta.ok) {
throw new Error("Error HTTP: " + respuesta.status);
}
return await respuesta.json();
} catch (error) {
console.error("Error:", error);
}
}
```
## Resumen
- Asíncrono: código que no bloquea la ejecución
- Callbacks: funciones pasadas como argumento (pueden causar callback hell)
- Promesas: `new Promise((resolve, reject) => {...})`
- Estados de promesa: pending, fulfilled, rejected
- `then/catch/finally` para manejar promesas
- `async/await`: sintaxis más limpia para promesas
- `Promise.all` para ejecutar múltiples promesas en paralelo
- `fetch` API para realizar solicitudes HTTP
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →