Programación Asíncrona
< Anterior Siguiente >La programación asíncrona en JavaScript es un enfoque que permite que el código se ejecute sin bloquear el hilo principal. Esto es particularmente útil en entornos del lado del cliente, donde el tiempo de respuesta es crucial para la experiencia del usuario. JavaScript maneja la asíncronía de varias maneras, incluyendo el uso de callbacks, promesas, y las palabras clave async
y await
.
1. Callbacks
Un callback es una función que se pasa como argumento a otra función y se ejecuta después de que se completa una operación. Este patrón era la forma más común de manejar la asíncronía en JavaScript antes de la introducción de las promesas y async/await
. Aunque efectivo, puede llevar a una complejidad conocida como "Callback Hell" (infierno de callbacks), donde las funciones anidadas se vuelven difíciles de leer y mantener.
// Ejemplo de Callback console.log("Inicio"); function fetchData(callback) { setTimeout(() => { console.log("Datos obtenidos"); callback(); }, 2000); } fetchData(() => { console.log("Procesando datos"); }); console.log("Fin"); // Output esperado: // Inicio // Fin // Datos obtenidos // Procesando datos
2. Promesas
Las promesas son objetos que representan la eventual finalización (o falla) de una operación asíncrona y su valor resultante. A diferencia de los callbacks tradicionales, las promesas proporcionan un flujo de control más limpio y evitan la necesidad de múltiples niveles de anidación.
Una promesa puede estar en uno de estos tres estados:
- Pendiente (Pending): Estado inicial, ni cumplida ni rechazada.
- Cumplida (Fulfilled): Operación completada con éxito.
- Rechazada (Rejected): Operación fallida.
// Ejemplo de Promesa let promesa = new Promise((resolve, reject) => { setTimeout(() => { resolve("Promesa cumplida"); }, 3000); }); promesa.then((mensaje) => { console.log(mensaje); }).catch((error) => { console.log(error); }); // Output esperado: // Promesa cumplida (después de 3 segundos)
3. Encadenamiento de Promesas
El encadenamiento de promesas permite que varias operaciones asíncronas se realicen en secuencia, con cada operación comenzando cuando se cumple la promesa anterior. Esto es útil para realizar tareas que dependen de operaciones previas.
// Ejemplo de Encadenamiento de Promesas new Promise((resolve, reject) => { setTimeout(() => resolve(1), 1000); }).then((resultado) => { console.log(resultado); // 1 return resultado * 2; }).then((resultado) => { console.log(resultado); // 2 return resultado * 2; }).then((resultado) => { console.log(resultado); // 4 }); // Output esperado: // 1 (después de 1 segundo) // 2 // 4
4. Async/Await
Las palabras clave async
y await
son una mejora sobre las promesas, proporcionando una sintaxis más clara y más fácil de entender para trabajar con operaciones asíncronas. Una función declarada con async
devuelve implícitamente una promesa, y el uso de await
dentro de una función async
permite esperar a que una promesa se resuelva antes de continuar.
// Ejemplo de Async/Await async function obtenerDatos() { try { let respuesta = await new Promise((resolve, reject) => { setTimeout(() => resolve("Datos recibidos"), 2000); }); console.log(respuesta); } catch (error) { console.log(error); } } obtenerDatos(); // Output esperado: // Datos recibidos (después de 2 segundos)
5. Fetch API
La Fetch API proporciona una interfaz moderna y poderosa para realizar solicitudes HTTP. A diferencia de XMLHttpRequest
, fetch()
devuelve una promesa que resuelve el objeto Response
de la solicitud.
// Ejemplo de Fetch API fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.log('Error:', error)); // Output esperado: // { ...datos de la API... } (dependerá de la respuesta de la API)
6. Ejemplo Completo de Async/Await con Fetch API
Combinar async/await
con la Fetch API permite manejar solicitudes de red de manera limpia y concisa.
// Ejemplo completo de Async/Await con Fetch API async function fetchData() { try { let response = await fetch('https://api.example.com/data'); let data = await response.json(); console.log(data); } catch (error) { console.log('Error:', error); } } fetchData(); // Output esperado: // { ...datos de la API... } o 'Error:' en caso de fallo