Skip to content
Aprende Angular de forma rápida y efectiva  Ver curso

Novedades de ES6: Promises

Probablemente ya sabes lo que es -en Javascript, se entiende- una promesa ( o promise en inglés), pero hasta la llegada de ES6, javascript no incorporaba promises por defecto, y para usarlas tenías que cargar librerías como JQuery o frameworks como AngularJS.

ES6 incorpora su propio mecanismo de Promises, y en este POST vas a ver como funcionan.

Promises, qué son

Las promesas se utilizan para la realización de tareas asíncronas, como por ejemplo la obtención de respuesta a una petición HTTP.

Una promesa puede tener 4 estados:

  • Pendiente: Es su estado inicial, no se ha cumplido ni rechazado.
  • Cumplida: La promesa se ha resuelto satisfactoriamente.
  • Rechazada: La promesa se ha completado con un error.
  • Arreglada: La promesa ya no está pendiente. O bien se ha cumplido, o bien se ha rechazado.

Sintaxis

new Promise(function(resolve, reject) { ... });

Cuando creamos una promise, le pasamos una función en cuyo interior deberían producirse las operaciones asíncronas, que recibe 2 argumentos:

  • Resolve: Es la función que llamaremos si queremos resolver satisfactoriamente la promesa.
  • Reject: Es la función que llamaremos si queremos rechazar la promesa.

Vamos a ver a grandes rasgos el contenido de una promise:

return new Promise(function(resolve, reject){

    //get some object that can do async tasks
    var asyncObj = new MyAsyncObj();

    //when async task ends successfully, resolve promise
    asyncObj.onSuccess = function(result){
        resolve(result);
    };
    //when async task ends with error, reject promise   
    asyncObj.onError = function(error){
        reject(error);
    }

    //perform async operation
    asyncObj.doSomething();
  })

Añadiendo callbacks a una promise

En el apartado anterior hemos visto como crear nuestra propia promesa, pero igual de importante es saber cómo decirle a una promesa qué tiene que ejecutar cuando se resuelve o rechaza.

Para eso tenemos 2 métodos:

  • Promise.prototype.catch(onRejected): Añade un callback que se ejecutará si la promise es rechazada, y devuelve la promise actualizada.
  • Promise.prototype.then(onFulfilled, onRejected): Añade un callback para caso de éxito, y otro para caso de error y devuelve la promise actualizada.

Vamos a ver un ejemplo de como añadiríamos callbacks a una promise:

let promise = new Promise(function(resolve, reject){
//...some stuff...
});

promise.then(
  function(value){
    console.log("success");
  },
  function(reason){
    console.log("error ", reason);
  }
);

promise.then(function(success){console.log("another callback")});

//if promise is resolved successfully, output will be:
//    success
//    another callback
//otherwise, output will be:
//    error "some reason"

Utilizando promises

Ahora que ya hemos visto como crear promesas y vincular callbacks para su resolución, vamos a ver un ejemplo completo de cómo crearíamos una promise para realizar una petición HTTP GET:

//Here we create the promise
function httpGET(url){
  return new Promise(function(resolve, reject){
    //create request object
    var request = new XMLHttpRequest();

    //callback to call when readyState changes
    request.onreadystatechange = function(){
      //check status when operation is completed
      if(request.readyState == 4){
        //if GET request is resolved with code 200, resolve promise
        if(request.status === 200){
          resolve(request.response);
        }
        //otherwise, reject promise
        else{
          reject(new Error(request.statusText));
        }
      }
    };

    //callback to call when error is received: reject promise
    request.onerror = function(){
      reject(new Error(this.statusText));
    };

    //initialize as GET request and set url
    request.open('GET', url);

    //send http get request
    request.send();
  });
};


//Here, we add callbacks
httpGET('http://codepen.io/chriscoyier/pen/difoC.html').then(function(value){
  console.log("success");
}, function(reason){
  console.log("error ", reason);
})

Conclusiones

Hace tiempo que las promises se han convertido en la vía más habitual de gestionar operaciones asíncronas. ES6 refuerza esta apuesta incorporando este mecanismo en la propia librería de Javascript, evitando dependencias con librerías externas. Si hasta ahora no utilizabas promises, ¡este es el momento de empezar!

Puedes mirar la documentación sobre promises para casos menos habituales de los que no he hablado, como iteradores de promesas.

¡Saludos!

Published inES6Javascript

Be First to Comment

Deja un comentario