Versiones comparadas

Clave

  • Se ha añadido esta línea.
  • Se ha eliminado esta línea.
  • El formato se ha cambiado.

...

Bloque de código
languagejs
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, devolviendo value.
  • reject(error) - si se ha producido un error, devolviendo el objeto error.

Cómo consumir objetos Promise

...

Bloque de código
languagejs
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
languagejs
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
languagejs
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
languagejs
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
languagejs
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
languagejs
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
languagejs
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.