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
yreject
. 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
y Promise.prototype.then
devuelven promesas, pueden ser encadenados—una operación llamada composición.Promise.prototype.catch
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 resuelve 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étodothen
), 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
oronRejected
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.enabled. Bug 918806 habilitado Promesas por defecto en Gecko 29.