Promesas en Javascript

Logo Javascript

¿Qué son las promesas en Javascript?

Las promesas en Javascript son un tipo de objeto sofisticado y poderoso que representa la terminación o el fracaso eventual de una operación asíncrona.

Este concepto es crucial en el mundo del desarrollo de Javascript, especialmente cuando se trata de operaciones asíncronas que tardan un tiempo en completarse, como puedes ser el caso de la lectura de archivos o las solicitudes de red.

Las promesas nos aportan una estructura y una organización muy necesarias, permitiendo a los desarrolladores manejar estas operaciones asíncronas de una manera mucho más intuitiva, fácil de entender y manejable.

Lo hacen proporcionando una forma sistemática de adjuntar callbacks para el éxito o el fracaso de las operaciones asíncronas, mejorando así la legibilidad y la mantenibilidad del código.

Estados de una Promesa

Es esencial que comprendamos los diferentes estados por los que puede pasar una Promesa cuando tratamos de gestionarla en el desarrollo de software. Estos estados son una parte fundamental del ciclo de vida de una Promesa y pueden influir significativamente en cómo se maneja la Promesa en el código. Los estados por los que puede pasar una Promesa son los siguientes:

  • Pending (pendiente), este es el estado inicial de una Promesa. En este estado, la Promesa aún no se ha resuelto ni rechazado. Esencialmente, la tarea que la Promesa representa todavía está en curso.
  • Fullfilled (cumplida), este es el estado que indica que la Promesa se ha resuelto con éxito. En otras palabras, la tarea que la Promesa representaba se ha completado de manera satisfactoria.
  • Rejected (rechazada), este estado indica que ha ocurrido un error en la tarea que la Promesa representaba. En este caso, la Promesa se ha rechazado debido a este error.

Definir una Promesa

Para definir una promesa simplemente deberemos de crear un nuevo objeto de tipo Promise.

Una promesa en Javascript se define utilizando la palabra clave new seguida de la clase Promise. La clase Promise acepta una función como argumento, que a su vez acepta dos parámetros: resolve y reject.

const promesa = new Promise((resolve,reject))

Estos parámetros son funciones que se invocan para indicar el éxito o el fracaso de la operación asíncrona.

De esta manera podríamos definir la siguiente promesa:

let promesa = new Promise((resolve, reject) => {
    let numero = Math.floor(Math.random()*6+1);
    if (numero == 3) {
        resolve({"mensaje":"Número Correcto","numero":numero});
    } else {
        reject({"mensaje":"Número Incorrecto","numero":numero});
    }
});

En este ejemplo, la promesa simula el lanzamiento de un dado y nos devolverá una condición correcta mediante resolve si el dado ha sacado un 3 y si no nos devolverá una condición errónea mediante reject.

¿Cómo se consume una promesa en Javascript?

Una vez que ya sabemos definir una promesa mediante el objeto Promise vamos a ver cómo se consume. Para ello tenemos que saber que existen tres métodos principales para su gestión: .then() que nos permite indicar una función para el éxito y otra para el fracaso de la promesa, .catch() que nos permite gestionar un error en la ejecución de la operación de la promesa y .finally() que será el último método en ejecutarse y que nos permitirá realizar gestiones de cierre o eliminación de los recursos en la operación.

Pero vamos a ver estos métodos un poco más en detalle:

.then()

El método .then() se encadena a la promesa y toma dos argumentos: una función de devolución de llamada para el éxito y otra para el fracaso de la promesa. Es decir, la función de devolución de llamada de éxito se ejecuta cuando se resuelve la promesa, mientras que la de fracaso se ejecuta cuando se rechaza.

La sintaxis del método .then()

p.then(onFulfilled[, onRejected]);
p.then(value => { // fulfillment }, reason => { // rejection });

De esta manera podemos utilizar el método .then() dentro de nuestro ejemplo de promesa anterior de la siguiente forma para gestionar una situación de cumplimiento:

promesa.then(valor => {console.log(valor.mensaje)});

O bien mediante el código:

promesa.then(valor => {console.log(valor.mensaje)},
             rechazo => {console.log(rechazo.mensaje)});

Para gestionar tanto la situación de cumplimiento como la situación de rechazo.

.catch()

El método .catch() se utiliza para manejar cualquier error que pueda ocurrir durante la ejecución de la operación asíncrona. Es similar al segundo argumento del método .then(), pero tiene la ventaja de poder manejar errores de varias promesas en una cadena de promesas.

La sintaxis del método .catch() es la siguiente:

p.catch(onRejected); 
p.catch(function(reason) { // rejection });

Si aplicamos el método .catch() en la promesa que habíamos definido al principio tendremos lo siguiente:

promesa.catch(valor => {console.log(valor.mensaje + " " + valor.numero)});

.finally()

Por último, .finally() es un método que se ejecuta siempre, independientemente de si la promesa se resolvió o se rechazó. Esto es útil para limpiar o finalizar cualquier recurso que se haya utilizado durante la operación asíncrona.

La sintaxis del método .finally() es la siguiente:

p.finally(onFinally);
p.finally(function() { // settled (fulfilled or rejected) });

En nuestro código no es que tengamos que liberar muchos recursos, pero si que podemos indicar que se ha terminado de procesar la promesa.

promesa.finally(()=>console.log("Fin ejecución de la promesa"));


Mejora esta página