En JavaScript podemos encontrarnos con código asíncrono, con el tipo de dato Promesa que, por ejemplo, obtenemos como respuesta de las llamadas a servicios REST con axios. Para tratar este código, tenemos dos formas principales: con los métodos .then(), .catch() y .finally() que proporcionan las promesas, o con async y await.
Tipo de dato Promise
En JavaScript, el tipo Promise es un objeto que se usa para funcionalidades asíncronas, y representa un valor que se resolverá en el futuro, ya sea con éxito o con error.
Crear objetos Promise
Aunque por lo general no necesitaremos crear nuestros propios Promise, es importante conocer cómo se haría. La sintaxis del constructor del objeto promise sería la siguiente:
let promise = new Promise(function(resolve, reject) {
// executor (el código que ejecutará la Promise)
});
La función que se le pasa al new Promise se llama executor, que se ejecuta automáticamente cuando se crea la Promise, y producirá el resultado. Esta función devuelve un resultado llamando a uno de estos dos callbacks:
resolve(value)- si la tarea ha finalizado con éxito, devolviendovalue.reject(error)- si se ha producido un error, devolviendo el objetoerror.
Cómo consumir objetos Promise
Utilizando .then(), .catch() y .finally()
Estos tres métodos tienen un funcionamiento que se asemeja al try - catch - finally que podemos conocer de Java. Se ejecuta el código que se indique en .then( ... ) si la promesa se resuelve correctamente, se ejecuta .catch( ... ) si da un error, y tras ejecutarse uno u otro, se ejecuta siempre .finally( ... ).
.then( ... )
El método principal para el tratamiento de las Promise será .then, pues nos permite tratar una promesa exitosa, pero también nos permite definir el tratamiento de errores, pudiendo ahorrarnos el .catch. El código a ejecutar en cada caso se definiría con dos funciones, de esta forma:
promise.then(
function(result) { /* Código en respuesta a un resultado exitoso */ },
function(error) { /* Código en respuesta a un error */ }
);
O de forma abreviada, con funciones flecha:
promise.then(
(result) => { /* Código en respuesta a un resultado exitoso */ },
(error) => { /* Código en respuesta a un error */ }
);
El primer argumento define la función que se ejecutará en el momento en el que se resuelva la promesa, y el segundo argumento la función que se ejecutará si se devuelve un error. Si solo estamos interesados en reaccionar a una respuesta exitosa, podemos indicar únicamente el primer argumento.
.catch( ... )
Con .catch podemos definir el tratamiento de problemas que se resuelven en error. Como hemos visto, este tratamiento se puede incluir como segundo argumento de .then, pero si queremos utilizarlo para que el código sea más legible, o porque solo queremos ejecutar código en caso de error, se haría así:
promise.catch((error) => { /* Código en respuesta a un error */ });
finally( ... )
Por último, la función que indiquemos en el .finally se ejecutará después de que la promesa haya dado un valor, ya sea correcto o error, y su sintaxis sería como en los casos anteriores:
promise.finally(() => alert("Promesa lista").then(result => alert(result));
promise.finally(() => alert("Promesa lista").catch(err => alert(err));
Una particularidad del finally es que realmente no tiene por qué ser el último código que se ejecute. Then catch y finally se ejecutan una vez se ha resuelto la promesa, pero si ponemos el finally antes de los otros métodos, su código se ejecutará antes, independientemente de cómo se haya resuelto la promesa.
Utilizando async/await
