Promesas en JavaScript: Una Introducción
¿Qué es una Promesa?
Imagina que eres un cantante famoso y tus seguidores te piden constantemente tu nueva canción. Para liberar un poco de presión, decides prometerles que se las enviarás tan pronto como salga. Les das una lista donde pueden registrar sus correos electrónicos, así que cuando la canción esté disponible, todos recibirán una notificación. Incluso si algo sale mal, como un incendio en el estudio, también serán informados.
Esta analogía representa bien algunos conceptos en programación:
- Un «código productor» que realiza una tarea que toma tiempo, como cargar datos a través de una red (el «cantante»).
- Un «código consumidor» que espera el resultado del «código productor» (los «fanáticos»).
- Una promesa, que actúa como el enlace entre ambos, asegurando que cuando el resultado esté disponible, se notificará a todos los interesados.
La Sintaxis de una Promesa
En JavaScript, una promesa es un objeto especial que vincula el «código productor» y el «código consumidor». La sintaxis para crear una promesa es:
let promise = new Promise(function(resolve, reject) {
// Código productor
});
La función pasada a new Promise
se llama «ejecutor». Este ejecutor se ejecuta automáticamente cuando se crea la promesa. Recibe dos parámetros: resolve
y reject
. Cuando la tarea se completa, resolve
se llama si tiene éxito, y reject
se llama si hay un error.
Ejemplo de una Promesa
Aquí hay un ejemplo básico:
let promise = new Promise(function(resolve, reject) {
setTimeout(() => resolve("¡Hecho!"), 1000);
});
En este caso, después de un segundo, la promesa se resuelve con el valor «¡Hecho!».
Manejo de Errores
También podemos manejar errores llamando a reject
:
let promise = new Promise(function(resolve, reject) {
setTimeout(() => reject(new Error("¡Vaya!")), 1000);
});
En este ejemplo, después de un segundo, la promesa se rechaza con un error.
Consumidores: then
y catch
Para manejar el resultado de una promesa, usamos los métodos .then
y .catch
.
then
El método then
se utiliza para manejar un resultado exitoso o un error:
promise.then(
result => alert(result), // Maneja el éxito
error => alert(error) // Maneja el error
);
catch
Si solo estamos interesados en manejar errores, podemos usar .catch
:
promise.catch(alert);
Limpieza con finally
El método finally
se ejecuta independientemente de si la promesa se resolvió o rechazó. Se utiliza para realizar tareas de limpieza:
new Promise((resolve, reject) => {
// Código productor
})
.finally(() => {
// Limpieza
})
.then(result => {
// Manejo del resultado
}, error => {
// Manejo del error
});
Ejemplo Práctico: Cargar un Script
Reescribamos una función para cargar un script usando promesas:
function loadScript(src) {
return new Promise(function(resolve, reject) {
let script = document.createElement('script');
script.src = src;
script.onload = () => resolve(script);
script.onerror = () => reject(new Error(`Error al cargar el script: ${src}`));
document.head.append(script);
});
}
Uso de la nueva función loadScript
:
let promise = loadScript("https://example.com/script.js");
promise.then(
script => alert(`¡${script.src} cargado!`),
error => alert(`Error: ${error.message}`)
);
promise.then(script => alert('Otro manejador...'));
Ventajas de las Promesas
Las promesas ofrecen un flujo de código más natural y flexibilidad:
- Podemos agregar múltiples manejadores a una promesa con
.then
. - Las promesas permiten que el código se escriba en el orden lógico de ejecución.
Conclusión
Las promesas en JavaScript mejoran la gestión de tareas asincrónicas, proporcionando una manera más limpia y manejable de trabajar con operaciones que toman tiempo. Con el uso adecuado de then
, catch
y finally
, podemos manejar resultados y errores de manera eficiente, manteniendo nuestro código claro y estructurado.