...
| Bloque de código | ||
|---|---|---|
| ||
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
...
| Bloque de código | ||
|---|---|---|
| ||
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:
...
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
Posteriormente a las promesas, se incluyeron async y await, con el que podemos hacer el tratamiento del código asíncrono con un código más limpio, pues si encadenamos varias promesas, los bloques vistos en el apartado anterior anidados pueden ser poco legibles.
Async
Async es un modificador que podemos añadir a las funciones para especificar que estas sean asíncronas:
| Bloque de código | ||
|---|---|---|
| ||
async function asyncCall() {
...
} |
De esta forma, lo que se hace es que esa función devuelva un Promise, aunque no la creemos explícitamente. Si una función no incluye el async, pero devuelve un Promise, se considera async igualmente.
Await
Cuando hacemos una llamada a una función asíncrona, es decir, que devuelva una Pormise, podemos incluir el await delante de la llamada:
| Bloque de código | ||
|---|---|---|
| ||
const response = await fetch(…); |
Lo que hace await es indicar que se espere a que la promesa se resuelva, y que se devuelva el resultado. Es decir, await bloquea la ejecución dentro de la función en la que nos encontramos hasta que se resuelva la promesa. Cuando usamos await, todo lo que haya debajo dentro de la función es como si se ejecutase en .then. Por ejemplo, teniendo este código:
| Bloque de código | ||
|---|---|---|
| ||
const response = await fetch(…);
const json = await response.json();
const foo = JSON.parse(json); // Using json here, even though my request was async! |
Este otro código sería equivalente:
| Bloque de código | ||
|---|---|---|
| ||
fetch(…)
.then(response => response.json())
.then(json => {
const foo = JSON.parse(json);
}); |
Pero hay que entender e insistir en que await encapsula el resto de la función en la que nos encontramos. Por explicarlo con un ejemplo, teniendo el siguiente código:
| Bloque de código | ||
|---|---|---|
| ||
async function asynchronousCall() { ... };
function callWithAwait() {
console.log("Entramos en callWithAwait");
var response = await asynchronousCall();
console.log("Promesa resuelta");
}
function funcionPrincipal() {
console.log("Inicio de función principal");
callWithAwait();
console.log("Fin de función principal")
} |
Suponiendo que asynchronousCall tarda unos segundos en resolverse, es decir, es lo último que termina, el último console.log de la función principal se ejecutaría antes. El orden en el que veríamos los logs sería este:
Inicio de función principal
Entramos en callWithAwait
Fin de función principal
Promesa resuelta
Si nos aclaramos más con .then, para aclararnos, este sería el código equivalente:
| Bloque de código | ||
|---|---|---|
| ||
async function asynchronousCall() { ... };
funcionPrincipal() {
console.log("Inicio de función principal");
console.log("Entramos en callWithAwait");
asynchronousCall().then(() => {
console.log("Promesa resuelta");
});
console.log("Fin de función principal")
} |
Teniendo claro el funcionamiento de await, y organizando nuestro código de acuerdo con éste, podemos usar indistintamente await o .then.