El objeto Promise (Promesa) es usado para computaciones asíncronas. Una promesa representa un valor que puede estar disponible ahora, en el futuro, o nunca.

Sintaxis

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

Parámetros

ejecutor
Una función con los argumentos resolver y rechazar. La función ejecutor es ejecutada inmediatamente por la implementación de la Promesa, pasándole las funciones resolver y rechazar (el ejecutor es llamado incluso antes de que el constructor de la Promesa devuelva el objeto creado). Las funciones resolver y rechazar, al ser llamadas, resuelven o rechazan la promesa, respectivamente. Normalmente el ejecutor inicia un trabajo asíncrono, y luego, una vez que es completado, llama a la función resolver para resolver la promesa o la rechaza si ha ocurrido un error.
Si un error es lanzado en la función ejecutor, la promesa es rechazada y el valor de retorno del ejecutor es rechazado.

Descripción

Una Promesa es un proxy para un valor no necesariamente conocido en el momento que es creada la promesa. Permite asociar manejadores que actuarán asincrónicamente sobre un eventual valor en caso de éxito, o la razón de falla en caso de una falla. Esto permite que métodos asíncronos devuelvan valores como si fueran síncronos: en vez de inmediatamente retornar el valor final, el método asíncrono devuelve una promesa de suministrar el valor en algún momento en el futuro.

Una Promesa se encuentra en uno de los siguientes estados:

  • pendiente (pending): estado inicial, no cumplida o rechazada.
  • cumplida (fulfilled): significa que la operación se completó satisfactoriamente.
  • rechazada (rejected): significa que la operación falló.

Una promesa pendiente puede ser cumplida con un valor, o rechazada con una razón (error). Cuando cualquiera de estas dos opciones sucede, los métodos asociados, encolados por el método then de la promesa, son llamados. (Si la promesa ya ha sido cumplida o rechazada en el momento que es anexado su correspondiente manejador, el manejador será llamado, de tal manera que no exista una condición de carrera entre la operación asíncrona siendo completada y los manejadores siendo anexados)

Como los métodos Promise.prototype.then() y Promise.prototype.catch() retornan promesas, éstas pueden ser encadenadas.

No confundir con: Varios lenguajes tienen mecanismos para evaluar perezosamente y postergar una computación, a los que también les llaman "promesas" - p.ej.: Scheme. Las promesas en JavaScript representan procesos que ya están sucediendo, y pueden ser encadenados con funciones callback. Si lo que se busca es evaluar perezosamente una expresión, se debe considerar la función flecha (arrow function) sin argumentos: f = () => expresión para crear la expresión evaluada perezosamente, y f() para evaluar.

Nota: Una promesa se dice que está determinada (settled) si se ha cumplido o si se ha rechazado, pero no está pendiente. Con promesas también se usa el término resuelta — esto significa que la promesa está determinada, o que se encuentra bloqueada dentro de una cadena de promesas. States and fates de Domenic Denicola contiene mas detalles sobre la terminología 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 de dos promesas: una que se cumple cuando todas las promesas en el argumento iterable han sido cumplidas, o una que se rechaza tan pronto como una de las promesas del argumento iterable es rechazada. Si la promesa retornada es cumplida, es cumplida con una arreglo de los valores de las promesas cumplidas en el mismo orden definido en el iterable. Si la promesa retornada es rechazada, es rechazada con la razón de la primera promesa rechazada en el iterable. Este método puede ser útil para agregar resultados de múltiples promesas
Promise.race(iterable)
Devuelve una promesa que se 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.ej. tiene un método then), la promesa devuelta "seguirá" este thenable, adoptando su eventual estado; de lo contraro la promesa devuelta será resuelta con el valor. Generalmente, si se quiere 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 el <button>. Esto crea una promesa que se cumplirá, aplicando window.setTimeout(), al contador de la promesa (partiendo desde 1) aleatoriamente cada 1-3 segundos. El constructor de la Promesa es usado para crearla.

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 síncrona 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 +
    ') Comenzó (<small>Comenzó el código sincrónico</small>)<br/>');

  // Hacemos una promesa: prometemos un contador numérico de esta promesa,
  // empezando por 1 (después de esperar 3s)
  var p1 = new Promise(
    // La función resolvedora es llamada con la
    // habilidad de resolver o rechazar la promesa
    function(resolve, reject) {
      log.insertAdjacentHTML('beforeend', thisPromiseCount +
        ') Comenzó la promesa (<small>Código asíncrono comenzó</small>)<br/>');

      // Esto es solo un ejemplo para crear asincronismo
      window.setTimeout(
        function() {
          // ¡Cumplimos la promesa!
          resolve(thisPromiseCount);
        }, Math.random() * 2000 + 1000);
    }
  );

  // Definimos qué hacer cuando la promesa es resuelta/cumplida con la llamada
  // al método then(). La llamada al método catch() define qué hacer si
  // la promesa es rechazada
  p1.then(
    // Registrar el valor de la promesa cumplida
    function(val) {
      log.insertAdjacentHTML('beforeend', val +
        ') Promesa cumplida (<small>Código asíncrono terminado.</small>)<br/>');
    })
  .catch(
    // Registrar la razón del rechazo
    function(reason) {
      console.log('Manejar promesa rechazada ('+reason+') aquí.');
    });

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

Este ejemplo es ejecutado cuando pulsas el botón. Necesitas un navegador que soporte Promise. Al pulsar el botón varias veces en un período corto de tiempo, verás las diferentes promesas siendo cumplidas una tras otra.

Cargando una imagen con XHR

Otro ejemplo sencillo utilizando Promise y XMLHttpRequest para cargar una imagen está disponible en el repositorio js-examples de MDN en GitHub. También puedes verlo en acción. Cada paso está comentado y te permite seguir de cerca la arquitectura detrás de las Promesas y XHR.

Especificaciones

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Promise' in that specification.
Standard Initial definition in an ECMA standard.
ECMAScript 2017 Draft (ECMA-262)
The definition of 'Promise' in that specification.
Draft  

Compatibilidad de navegadores

Feature Chrome Edge Firefox Internet Explorer Opera Safari Servo
Promise32.0(Si)29.01Sin soporte197.12Sin soporte
Promise.all32.0(Si)29.0Sin soporte197.1Sin soporte
Promise.prototype32.0(Si)29.0Sin soporte197.1Sin soporte
Promise.prototype.catch32.0(Si)29.0Sin soporte197.1Sin soporte
Promise.prototype.then32.0(Si)29.0Sin soporte197.1Sin soporte
Promise.race32.0(Si)29.0Sin soporte197.1Sin soporte
Promise.reject32.0(Si)29.0Sin soporte197.1Sin soporte
Promise.resolve32.0(Si)29.0Sin soporte197.1Sin soporte
Feature Android Chrome for Android Edge Mobile Firefox for Android IE Mobile Opera Mobile Safari Mobile
Promise4.4.432.0(Si)291Sin soporte(Si)8.02
Promise.all4.4.432.0(Si)29Sin soporte(Si)8.0
Promise.prototype4.4.432.0(Si)29Sin soporte(Si)8.0
Promise.prototype.catch4.4.432.0(Si)29Sin soporte(Si)8.0
Promise.prototype.then4.4.432.0(Si)29Sin soporte(Si)8.0
Promise.race4.4.432.0(Si)29Sin soporte(Si)8.0
Promise.reject4.4.432.0(Si)29Sin soporte(Si)8.0
Promise.resolve4.4.432.0(Si)29Sin soporte(Si)8.0

1. Constructor requires a new operator since version 37.

2. Constructor requires a new operator since version 10.

Ver también

Etiquetas y colaboradores del documento

 Última actualización por: atpollmann,