This is an experimental technology, part of the ECMAScript 6 (Harmony) proposal.
Because this technology's specification has not stabilized, check the compatibility table for usage in various browsers. Also note that the syntax and behavior of an experimental technology is subject to change in future version of browsers as the spec changes.
The Promise
object is used for deferred and asynchronous computations. A Promise
is in one of these states:
- pending: initial state, not fulfilled or rejected.
- fulfilled: successful operation
- rejected: failed operation.
- settled: the Promise is either fulfilled or rejected, but not pending.
Syntax
new Promise(executor); new Promise(function(resolve, reject) { ... });
Parameters
- executor
- Function object with two arguments
resolve
andreject
. The first argument fulfills the promise, the second argument rejects it. We can call these functions, once our operation is completed.
Description
The Promise
interface represents a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers to an asynchronous action's eventual success or failure. This lets asynchronous methods return values like synchronous methods: instead of the final value, the asynchronous method returns a promise of having a value at some point in the future.
A pending promise can become either fulfilled with a value, or rejected with a reason. When either of these happens, the associated handlers queued up by a promise's then
method are called. (If the promise has already been fulfilled or rejected when a corresponding handler is attached, the handler will be called, so there is no race condition between an asynchronous operation completing and its handlers being attached.)
As the
and Promise.prototype.then
methods return promises, they can be chained—an operation called composition.Promise.prototype.catch
Properties
Promise.length
- Length property whose value is 1 (number of constructor arguments).
Promise.prototype
- Represents the prototype for the
Promise
constructor.
Methods
Promise.all(iterable)
- Returns a promise that resolves when all of the promises in the iterable argument have resolved.
Promise.race(iterable)
- Returns a promise that resolves or rejects as soon as one of the promises in the iterable resolves or rejects, with the value or reason from that promise.
Promise.reject(reason)
- Returns a
Promise
object that is rejected with the given reason.
Promise.resolve(value)
- Returns a
Promise
object that is resolved with the given value. If the value is a thenable (i.e. has athen
method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the value.
Promise
prototype
Properties
-
Promise.prototype.constructor
-
Returns the function that created an instance's prototype. This is the
Promise
function by default.
Methods
-
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.
Examples
Creating a Promise
This small example shows the mechanism of a Promise
. The testPromise()
method is called each time the <button>
is clicked. It creates a promise that will resolve, using window.setTimeout
, to the string 'result'
after 1s to 3s
(random).
The fulfillment of the promise is simply logged, via a fulfill callback set using p1.then
. A few logs shows how the synchronous part of the method is decoupled of the asynchronous completion of the promise.
var promiseCount = 0; function testPromise() { var thisPromiseCount = ++promiseCount; var log = document.getElementById('log'); log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Started (<small>Sync code started</small>)<br/>'); // We make a new promise: we promise the string 'result' (after waiting 3s) var p1 = new Promise( // The resolver function is called with the ability to resolve or // reject the promise function(resolve, reject) { log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Promise started (<small>Async code started</small>)<br/>'); // This only is an example to create asynchronism window.setTimeout( function() { // We fulfill the promise ! resolve(thisPromiseCount) }, Math.random() * 2000 + 1000); }); // We define what to do when the promise is fulfilled p1.then( // Just log the message and a value function(val) { log.insertAdjacentHTML('beforeend', val + ') Promise fulfilled (<small>Async code terminated</small>)<br/>'); }); log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Promise made (<small>Sync code terminated</small>)<br/>'); }
This example is executed when clicking the button. You need a browser supporting Promise
. By clicking several times the button in a short amount of time, you'll even see the different promise being fulfilled one after the other.
Example using new XMLHttpRequest()
Creating a Promise
This example shows the implementation of a method of success callback and error in XMLHttpRequest Interestingly enough.
'use strict'; // A-> $http function is implemented in order to follow the standard Adapter pattern function $http(url){ // A small example of object var core = { // Method that performs the ajax request ajax : function (method, url, args) { // Creating a promise var promise = new Promise( function (resolve, reject) { // Instantiates the 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) { // Performs the function "resolve" when this.status is equal to 200 resolve(this.response); } else { // Performs the function "reject" when this.status is different than 200 reject(this.statusText); } }; client.onerror = function () { reject(this.statusText); }; }); // Return the promise return promise; } }; // Adapter pattern 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); } }; }; // End A // B-> Here you define its functions and its payload 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)); } }; // End B // Executes the method call $http(mdnAPI) .get(payload) .then(callback.success) .catch(callback.error);
Loading an image with XHR
Another simple example using Promise
and XMLHttpRequest
to load an image is available at the MDN GitHub promise-test repository. You can also see it in action. Each step is commented and allows you to follow the Promise and XHR architecture closely.
Specifications
Specification | Status | Comment |
---|---|---|
ECMAScript 6 (ECMA-262) The definition of 'Promise' in that specification. |
Release Candidate | Initial definition in an ECMA standard. |
Browser compatibility
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | 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 |
Feature | Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile | Chrome for Android |
---|---|---|---|---|---|---|
Basic support | Not supported | 24.0 (24.0) as Future 25.0 (25.0) as Promise behind a flag[1]29.0 (29.0) by default |
Not supported | Not supported | iOS 8 | 32 |
[1] Gecko 24 has an experimental implementation of Promise
, under the initial name of Future
. It was renamed to its final name in Gecko 25, but disabled by default behind the flag dom.promise.enabled
. Bug 918806 enabled Promises by default in Gecko 29.