JavaScript Asincrono
Callbacks, Promises, async/await
Programacion Asincrona
JavaScript es single-threaded pero puede manejar operaciones asincronas sin bloquear la ejecucion. Esto es crucial para operaciones como peticiones de red, timers y manejo de archivos.
Callbacks
// Callback basico
function obtenerDatos(callback) {
setTimeout(() => {
const datos = { id: 1, nombre: "Ana" };
callback(datos);
}, 1000);
}
obtenerDatos((datos) => {
console.log(datos); // { id: 1, nombre: "Ana" }
});
// Callback hell (problema con callbacks anidados)
obtenerUsuario(id, (usuario) => {
obtenerPedidos(usuario.id, (pedidos) => {
obtenerDetalles(pedidos[0].id, (detalles) => {
// Codigo muy anidado y dificil de leer
});
});
});
Promises
// Creando una Promise
const miPromesa = new Promise((resolve, reject) => {
const exito = true;
setTimeout(() => {
if (exito) {
resolve({ id: 1, nombre: "Ana" });
} else {
reject(new Error("Algo salio mal"));
}
}, 1000);
});
// Consumiendo una Promise
miPromesa
.then((datos) => {
console.log("Exito:", datos);
return datos.id; // Retorna valor para siguiente .then
})
.then((id) => {
console.log("ID:", id);
})
.catch((error) => {
console.error("Error:", error.message);
})
.finally(() => {
console.log("Siempre se ejecuta");
});
async/await
// Funcion asincrona
async function obtenerUsuario() {
try {
const respuesta = await fetch("/api/usuario");
const usuario = await respuesta.json();
return usuario;
} catch (error) {
console.error("Error:", error);
throw error;
}
}
// Llamar funcion asincrona
obtenerUsuario()
.then(usuario => console.log(usuario))
.catch(error => console.error(error));
// O dentro de otra funcion async
async function main() {
const usuario = await obtenerUsuario();
console.log(usuario);
}
main();
Fetch API
// GET request
async function obtenerDatos() {
const respuesta = await fetch("https://api.ejemplo.com/datos");
if (!respuesta.ok) {
throw new Error(`HTTP error! status: ${respuesta.status}`);
}
const datos = await respuesta.json();
return datos;
}
// POST request
async function crearUsuario(usuario) {
const respuesta = await fetch("https://api.ejemplo.com/usuarios", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(usuario)
});
return respuesta.json();
}
// Uso
crearUsuario({ nombre: "Ana", email: "ana@ejemplo.com" })
.then(nuevoUsuario => console.log(nuevoUsuario));
Multiples Promesas
const promesa1 = fetch("/api/usuarios");
const promesa2 = fetch("/api/productos");
const promesa3 = fetch("/api/pedidos");
// Promise.all - espera a que todas se resuelvan
const resultados = await Promise.all([promesa1, promesa2, promesa3]);
// Si una falla, todas fallan
// Promise.allSettled - espera a todas, sin importar resultado
const resultados2 = await Promise.allSettled([promesa1, promesa2, promesa3]);
// [{ status: "fulfilled", value: ... }, { status: "rejected", reason: ... }]
// Promise.race - retorna la primera en resolver/rechazar
const primeraRespuesta = await Promise.race([promesa1, promesa2]);
// Promise.any - retorna la primera en resolver (ignora rechazos)
const primeraExitosa = await Promise.any([promesa1, promesa2]);