Promesas Javascript

en pocas palabras.

Las promesas permiten envolver peticiones asíncronas y encadenarlas para evitar el conocido callback hell, por lo que el código es mas fácil de entender y mantener.

Contenido

    Peticiones sin Promesas

    En la antigüedad cuando se requería realizar una solicitud asíncrona a un servidor se tenía que utilizar el objeto XMLHttpRequest, en el cual se tenía que indicar un callback para manejar el resultado.

    JavaScript
    const req = new XMLHttpRequest();
    req.addEventListener("load", function () {
      console.log(this.responseText);
    });
    req.open("GET", "http://somedomain/service1");
    req.send();

    Esto no tenía ninguna complicación siempre y cuando solo necesitaramos una sola petición, pero la realidad nunca es tan simple, en algunos casos requeriamos realizar una segunda petición justo cuando la primera terminara correctamente, y luego de esa segunda, tal vez otra y asi sucesivamente.

    Para lograr esto tras cada petición se tenía que realizar una solicitud en el callback exitoso con la nueva petición y esto generaba un callback, dentro de otro callback y asi sucesivamente por lo que se caería en lo que se conoce como callback hell.

    JavaScript
    const req1 = new XMLHttpRequest();
    req1.addEventListener("load", function () {
      if (this.status == 200) {
        const req2 = new XMLHttpRequest();
        req2.open("GET", "http://somedomain/service2");    
        req2.addEventListener("load", function () {
          // aqui otra petición y asi sucesivamente
        });
        req2.send();
      }
    });
    req1.open("GET", "http://somedomain/service1");
    req1.send();

    por suerte para nosotros llegaron las promesas y en vez de tener un callback dentro de otro callback, ahora podemos encadenar promesas con .then() continua leyendo para entender como vamos a hacerlo.

    Envolviendo Peticiones

    Si queremos resolver el problema de callback hell con nuestro famoso XMLHttpRequest vamos a necesitar convertirlo en promesa para luego poder encadenar cada petición y hacer nuestro código mas limpio y mantenible gracias a las promesas.

    JavaScript
    function makeRequest(){
      return new Promise(function(resolve,reject){
        const req = new XMLHttpRequest();
        req.addEventListener("load", function () {
          if (req.status == 200) {
            resolve(req.response);
          }else{
            reject('error');
          }
        });
        req.open("GET", "http://somedomain/service1");
        req.send();
      });
    }
    
    makeRequest().then(
      function(result){
        //en caso de que todo este bien
      },
      function(result){
        //en caso de error
      }
    );

    Envolver requiere algo de esfuerzo, pero la buena noticia es que actualmente contamos con fetch, el cual automaticamente devuelve una promesa y no tenemos que realizar este trabajo de envolver cada petición. A continuación el mismo ejemplo pero usando fetch.

    JavaScript
    function makeRequest(){
      return fetch("http://somedomain/service1");
    }
    
    makeRequest().then(
      function(result){
        //en caso de que todo este bien
      },
      function(result){
        //en caso de error
      }
    );

    Encadenando Promesas

    Encadenar promesas es la gracia de las promesas, de esta manera evitamos el conocido callback hell y nuestro código crece de forma mas ordenada. Resulta que tras la ejecución de una promesa podemos acceder al resultando con el metodo .then(), el cual lo podemos utilizar para devolver una promesa y con ello el código crece de forma lineal y no en forma de un callback dentro de un callback, asi evitando el callback hell.

    JavaScript
    function req1(){
      return fetch("http://somedomain/service1");
    }
    
    function req2(){
      return fetch("http://somedomain/service2");
    }
    
    req1()
    .then(function(response){
      //resultado de la primera solicitud.
      return req2();
    })
    .then(function(response){
      //resultado de la segunda solicitud.
    }); //podriamos seguir encadenando mas peticiones.

    Otros Detalles

    Algunos detalles importantes de las promesas fueron excluidos debido a que podrian generar confusión, sin embargo son importantes estudiarlos y entenderlos en detalle.

    • Las promesas tienen gestion de errores y estan se controlan con el metodo .catch()
    • El método .then() tiene sobrecarga de su método tanto en sus parámetros como en el valor retornado. Esto podría confundir, asi que leer atentamente este método.
    • muchos desarrolladores no suelen utilizar una función para la creación de la promesa, en vez de ello utilizan la promesa directamente ejemplo: fetch("http://somedomain/service1").then(...) al igualmente para los valores retornados, ejemplo: return fetch("http://somedomain/service2");
    • Debido a que puede ser complejo aprender y utilizar correctamente las promesas en la forma clasica (como se presenta en este árticulo) se creo async/await, esta utilizan las promesas, y permite que el código sea mas fácil de entender, aprender y mantener.

    Conclusiones

    • Las promesas nacen de la necesidad para que el código sea mas ordenado y fácil de mantener evitando el callback hell.
    • Las promesas pueden ser difíciles de entender por lo que lo que aprenderlas y utilizarlas correctamente puede tomar algo de tiempo.

    Gracias por leer.

    Commentarios

    Leave a Reply

    Your email address will not be published. Required fields are marked *