El objeto Promise se usa para computaciones diferidas o asíncronas. Una Promesa puede estar en uno de estos estados:

  • pending ( pendiente ): estado inicial, no cumplida o rechazada.
  • fulfilled ( cumplida ): operación satisfactoria.
  • rejected ( rechazada ): operación fallida.

Sintaxis

new Promise(ejecutor);
new Promise(function(resolver, rechazar) { ... });

Parámetros

ejecutor

Objeto Function con dos argumentos resolve y reject. El primer argumento cumple la promesa, el segundo argumento la rechaza. Podemos llamar a estas funciones, una vez que se haya completado nuestra operación.

Descripción

La interfaz Promise representa un proxy para un valor no necesariamente conocido cuando se crea la promesa. Permite asociar manejadores a un eventual éxito o fracaso de acciones asíncronas. Esto permite que los métodos asíncronos devuelvan valores como métodos sincrónicos: en lugar del valor final, el método asíncrono devuelve una promesa de tener un valor en algún momento en el futuro.

Una promesa pendiente puede llegar a ser cumplida con un valor o rechazada con una razón. Cuando cualquiera de ellas sucede, los manejadores asociados encolados se llaman mediante el método then de la promesa. (Si la promesa ya se ha cumplido o rechazado cuando se conecta un controlador correspondiente, el manejador será llamado, así que no hay condición de carrera entre el final de una operación asincrónica y sus manejadores se adjuntan).

Como los métodos Promise.prototype.thenPromise.prototype.catch devuelven promesas, pueden ser encadenados—una operación llamada composición.

Nota: Una promesa se dice que está settled ( determinada ) si se ha cumplido o si se ha rechazado, pero no está pendiente. También verás el término resuelta usado con promesas — esto significa que la promesa está determinada, o que está fijada por una cadena de promesas. States and fates de Domenic Denicola contiene mas detalles sobre la terminologia de las promesas.

Propiedades

Promise.length
Propiedad longitud cuyo valor es 1 (numero de argumentos del constructor).
Promise.prototype
Representa el prototipo del constructor Promise.

Métodos

Promise.all(iterable)
Devuelve una promesa que se resuleve cuando todas las promesas del argumento iterable han sido resueltas.
Promise.race(iterable)
Devuelve una promesa que resuelve o rechaza tan pronto como una de las promesas del iterable se resuelve o rechaza, con el valor o razón de esa promesa.
Promise.reject(reason)
Devuelve un objeto Promise que es rechazado con la razón dada.
Promise.resolve(value)
Devuelve un objeto Promise que es resuelto con el valor dado.. Si el valor es un thenable (p.e. tiene un método then), la promesa devuelta "seguirá" este thenable, adoptando su estado eventual; de lo contraro la promesa devuelta será resuelta con el valor. Generalmente, si quieres saber si un valor es una promesa o no, se podría usar - Promise.resolve(value) y trabajar con el valor devuelto como una promesa.

Prototipo Promise

Propiedades

Promise.prototype.constructor
Returns the function that created an instance's prototype. This is the Promise function by default.

Métodos

Promise.prototype.catch(onRejected)
Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled.
Promise.prototype.then(onFulfilled, onRejected)
Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler, or to its original settled value if the promise was not handled (i.e. if the relevant handler onFulfilled or onRejected is not a function).

Ejemplos

Creando una promesa

Este pequeño ejemplo muestra el mecanismo de una Promesa. El método testPromise() se llama cada vez que se pulsa <button>. Esto crea una promesa que se resolverá, usando window.setTimeout, con la cadena 'resultado' despues de entre 1 y 3 segundos, es aleatorio.

El cumplimiento de la promesa simplemente se registra, a través de una llamada de retorno al cumplirse utilizando p1.then. A los pocos registros muestra cómo la parte sincróna del método se desacopla de la finalización asíncrona de la promesa.

'use strict';
var promiseCount = 0;

function testPromise() {
  var thisPromiseCount = ++promiseCount;

  var log = document.getElementById('log');
  log.insertAdjacentHTML('beforeend', thisPromiseCount + 
      ') Started (<small>Código sincrónico empezado</small>)<br/>');

  // Hacemos una nueva promesa: prometemos la cadena 'resultado' (después de esperar 3s)
  var p1 = new Promise(
    // La función de resolución se llama con la capacidad de  
    // resolver o rechzar la promesa
    function(resolve, reject) {       
      log.insertAdjacentHTML('beforeend', thisPromiseCount + 
          ') Promesa empezada (<small>Código asíncrono empezado</small>)<br/>');
      // Esto sólo es un ejemplo para crear asincronismo
      window.setTimeout(
        function() {
          // ¡Cumplimos la promesa!
          resolve(thisPromiseCount)
        }, Math.random() * 2000 + 1000);
    });

  // definimos que hacer cuando la promesa se ha cumplido.
  p1.then(
    // Solo registramos el mensaje y un valor.
    function(val) {
      log.insertAdjacentHTML('beforeend', val +
          ') Promesa cumplida (<small>Código asíncrono terminado</small>)<br/>');
    });

  log.insertAdjacentHTML('beforeend', thisPromiseCount + 
      ') Promesa hecha (<small>Código sincrónico terminado</small>)<br/>');
}

Este ejemplo es ejecutado cuando pulsas el botón. Necesitas un navegador que soporte Promise. Pulsando varias veces el botón en un periodo corto de tiempo, incluso verás la diferente promesa siendo cumpliendo una tras otra.

Ejemplo usando el nuevo XMLHttpRequest()

Creando una Promesa

Este ejemplo muestra la implementación de un método de llamada de retorno de éxito o error con XMLHttpRequest bastante interesante.

'use strict';

// A-> la función $http se implementa con el fin de seguir el modelo de Adapter estándar
function $http(url){
 
  // Un pequeño ejemplo de objeto
  var core = {

    // Método que realiza la petición AJAX
    ajax : function (method, url, args) {

      // Creando una promesa.
      var promise = new Promise( function (resolve, reject) {

        // Instancia XMLHttpRequest
        var client = new XMLHttpRequest();
        var uri = url;

        if (args && (method === 'POST' || method === 'PUT')) {
          uri += '?';
          var argcount = 0;
          for (var key in args) {
            if (args.hasOwnProperty(key)) {
              if (argcount++) {
                uri += '&';
              }
              uri += encodeURIComponent(key) + '=' + encodeURIComponent(args[key]);
            }
          }
        }

        client.open(method, uri);
        client.send();

        client.onload = function () {
          if (this.status == 200) {
            // Realiza la función "resolver" cuando this.status es igual a 200
            resolve(this.response);
          } else {
            // Realiza la función "rechazar" when this.status es diferente de 200
            reject(this.statusText);
          }
        };
        client.onerror = function () {
          reject(this.statusText);
        };
      });

      // Return the promise
      return promise;
    }
  };

  // Patrón Adapter
  return {
    'get' : function(args) {
      return core.ajax('GET', url, args);
    },
    'post' : function(args) {
      return core.ajax('POST', url, args);
    },
    'put' : function(args) {
      return core.ajax('PUT', url, args);
    },
    'delete' : function(args) {
      return core.ajax('DELETE', url, args);
    }
  };
};
// Fin A

// B-> Aquí se definen sus funciones y su playload
var mdnAPI = 'https://developer.mozilla.org/en-US/search.json';
var payload = {
  'topic' : 'js',
  'q'     : 'Promise'
};

var callback = {
  success : function(data){
     console.log(1, 'success', JSON.parse(data));
  },
  error : function(data){
     console.log(2, 'error', JSON.parse(data));
  }
};
// Fin B

// Ejecutra la llamada al método
$http(mdnAPI)
  .get(payload)
  .then(callback.success)
  .catch(callback.error);

Cargando una imagen con XHR

Otro ejemplo sencillo utilizando Promise y XMLHttpRequest para cargar una imagen está disponible en el repositorio de GitHub de MDN promise-test. También puedes verlo en acción. Cada paso está comentado y te permite seguir de cerca la arquitectura Promesa y XHR architecture.

Especificaciones

Especificación Estado Comentario
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Promise' in that specification.
Standard Initial definition in an ECMA standard.

Compatibilidad de navegadores

Característica Chrome Firefox (Gecko) Internet Explorer Opera Safari
Soporte básico 32 24.0 (24.0) as Future
25.0 (25.0) as Promise behind a flag[1]
29.0 (29.0) by default
11 (Modern.IE status) 19 7.1
Característica Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile Chrome for Android
Soporte básico No support 24.0 (24.0) as Future
25.0 (25.0) as Promise behind a flag[1]
29.0 (29.0) by default
No support No support iOS 8 32

[1] Gecko 24 tiene una aplicación experimental de Promise, bajo el nombre inicial de Future. Su nombre se cambió a su nombre definitivo en Gecko 25, pero desactivado por defecto tras la flag dom.promise.enabledBug 918806 habilitado Promesas por defecto en Gecko 29.

Ver también

Etiquetas y colaboradores del documento

 Última actualización por: luisrodriguezchaves,