Promise

Las promesas

Para manejar tareas asíncronas Javascript puede hacer uso de los objetos promise. Se trata de un objeto capaz de hacer una llamada a una tarea y responder en función del resultado de como se ejecute esa tarea, habitualmente una tarea asíncrona.

Cuando se crea una promesa creas un objeto que te dará una respuesta en el futuro.

En general el objeto promise puede estar en tres estados:

  • Espera: el proceso asíncrono lanzado no ha finalizado aún
  • Cumplida: el proceso se ha completado con éxito
  • Rechazado: el proceso no se pudo ejecutar o hubo un error.

Una promesa me permite que el proceso continue su ejecución despues de lanzar la promesa. Al devolver el resultado sendas funciones callback se encargarán de procesarlo.

Un simil de la vida cotidiana podría ser: mientras realizo mis tareas cotidianas en la casa llamo al restaurante pidiendo una reserva para la cena. El restaurante toma nota y me promete una respuesta a mi petición. Mientras llega la respuesta yo sigo con mis tareas. Cuanod llega la respuesta avisaré a mi pareja para que sepa que cenamos en el restaurante o que cenamos en la casa si no es posible hacer la reserva.

Esto mismo en un script sería este código

var sitio;

function haySitio(){

   return Math.ceil(Math.random()*10)%2 == 0

};

//Crear la promesa:

//el restaurante promete: si hay sitio nos da reserva

var pedirReserva = new Promise(function (resolve, reject) {

    setTimeout(function(){

       sitio = haySitio();

       if (sitio) {

           var cena = {restaurante: "Delicias",

                             hora: '21:00'};

            resolve(cena); // completada con éxito

      }

        else {

            var motivo = 'No hay sitio';

            reject(motivo); // rechazada o error

}

        }, 2000);

});

function reservar(promesa){

    console.log("Llamar al restaurante");

    promesa.then(

    function(cena){

        console.log('Hola tenemos reserva en ');

        console.log(cena.restaurante+" a las "+cena.hora);

    },

    function(motivo){

        console.log('Cenamos en casa porque '+motivo);

    }

);

console.log("Respuesta del restaurante");

};

reservar(pedirReserva);

Este sería un uso muy básico de una promesa para mostrar el mecanismo de funcionamiento de las promesas en Javascript.

Cmo vemos una promesa se crea como cualquier objeto mediante el operador new. Lleva como argumento una función con dos parámetros: resolve y reject

  • resolve: una función que se ejecutará si la promesa se cumple
  • reject: una función que se ejecutará si la promesa falla (o hay un error)

La función invoca una tarea, en este caso se simula mediante un setTimeout() que llamará a la función haySitio() encargada de comprobar si hay sitio en el restaurante (como ves una simple función aleatoria). Si la promesa se cumple (hay sitio) pues se ejecuta la función resolve y sino pues se ejecuta la función reject.

Ahora toca responder a la promesa. Para esto el objeto promise posee el método then(resolve, reject), es el método que invoca a las funciones usadas como argumentos al definir el objeto promise. En el ejemplo se usan funciones anónimas: la primera responde a la promesa cumplida y la segunda a la no cumplida.Como argumento llevan el enviado por resolve y reject de la definición de la promise

En el ejemplo he puesto salidas de consola para ver el flujo de funcionamiento e ilustar como trabaja la promesa. Observa que la salida es

Llamar al restaurante

Respuesta del restaurante

Cenamos en casa: No hay sitio

Pese a que en el código el orden es secuencial, por lo que las lineas 2 y 3 están al revés. Además la última línea, la respuesta del restaurante, tarda en mostrarse. En ese tiempo el script no tiene que esperar, podría seguir haciendo otras cosas.

Existe un método para capturar errores en la ejecución del proceso controlado por la promesa es promise.catch(), que realmente usa una llamada al método promise.then (reject).

Algo importante es saber que el método promise.then devuelve otra promesa, por lo que las promesas se pueden encadenar.

Notas

Las promesas no son tareas asíncronas, son objetos con los que responder a tareas asíncronas.

Una promesa puede ser vista como un objeto cuyo valor no está disponible en el momento de su creación.

Las promesas se consumen, se reciben, usando el método then(). Este método responde al estado cumplido o rechazado resultante al finalizar la tarea llamada por la promesa.

El método then puede devolver un valor u otra promesa.

 Promise en javascript

 

Las promesas pueden agruparse. Para ello se usan los métodos estáticos a las que se les pasa como argumentos las promesas que se agrupen.

  • all() El grupo pasa a estado resuelto si todas las promesas pasan a ese estado
  • any() pasa al estado resuelto correspondiente a la primera de las promesas que ha sido resuelta
  • allSettled() cuando todas las promesas han finalizado devuelve un array con el estado de cada una: cumplida o rechazada.

Son métodos estáticos, se usan con el nombre dell objeto como prefijo: Promise.all(prom1, prom2, prom3)

El uso más habitual de las promises es en las operaciones tipo AJAX, o su sucesor Fetch(), tareas que permiten al navegador comunicarse con el servidor sin necesidad de recargarse.