Apply your JS skills to key Mozilla projects as an MDN Fellow! http://mzl.la/MDNFellowship

mozilla

Revision 612087 of Promise

  • Revision slug: Web/JavaScript/Reference/Global_Objects/Promise
  • Revision title: Promise
  • Revision id: 612087
  • Created:
  • Creator: Daniel Biddle
  • Is current revision? No
  • Comment

Revision Content

{{SeeCompatTable}}

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 Promise.prototype.then and Promise.prototype.catch methods return promises, they can be chained—an operation called composition.

Methods

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.
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.

Static methods

Promise.resolve(value)
Returns a Promise object that is resolved with the given value. If the value is a thenable (i.e. has a then method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the value.
Promise.reject(reason)
Returns a Promise object that is rejected with the given reason.
Promise.all(iterable)
Returns a promise that resolves when all of the promises in iterable have resolved. The result is passed an array of values from all the promises. If something passed in the iterable array is not a promise, it's converted to one by Promise.cast. If any of the passed in promises rejects, the all Promise immediately rejects with the value of the promise that rejected, discarding all the other promises whether or not they have resolved.
var p = new Promise(function(resolve, reject) { resolve(3); });
Promise.all([true, p]).then(function(values) {
  // values == [ true, 3 ]
});
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.
var p1 = new Promise(function(resolve, reject) { setTimeout(resolve, 500, "one"); });
var p2 = new Promise(function(resolve, reject) { setTimeout(resolve, 100, "two"); });

Promise.race([p1, p2]).then(function(value) {
  // value === "two"
});

var p3 = new Promise(function(resolve, reject) { setTimeout(resolve, 100, "three"); });
var p4 = new Promise(function(resolve, reject) { setTimeout(reject, 500, "four"); });

Promise.race([p3, p4]).then(function(value) {
  // value === "three"               
}, function(reason) {
  // Not called
});

var p5 = new Promise(function(resolve, reject) { setTimeout(resolve, 500, "five"); });
var p6 = new Promise(function(resolve, reject) { setTimeout(reject, 100, "six"); });

Promise.race([p5, p6]).then(function(value) {
  // Not called              
}, function(reason) {
  // reason === "six"
});

Example

This small example shows the mechanism of a Promise. The testPromise() method is called each time the {{HTMLElement("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/>');

  var p1 = new Promise(               /* We make a new promise: we promise the string 'result' (after waiting 3s) */
    function(resolve, reject) {       /* The resolver function is called with the ability to resolve or reject the promise */
      log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Promise started (<small>Async code started</small>)<br/>');
      window.setTimeout(              /* This only is an example to create asynchronism */
        function() {
          resolve(thisPromiseCount); /* We fulfill the promise ! */
        }, Math.random() * 2000 + 1000);
    });

  p1.then(                            /* We define what to do when the promise is fulfilled */
    function(val) {                   /* Just log the message and a value */
      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.

{{EmbedLiveSample("Example", "500", "300")}}

Specification

Specification Status Comment
domenic/promises-unwrapping Draft Initial work is taking place here
ES6 Draft Eventually it will be transferred to the full ES6 draft

Browser compatibility

{{CompatibilityTable}}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 32 {{CompatGeckoDesktop(24.0)}} as Future
{{CompatGeckoDesktop(25.0)}} as Promise behind a flag[1]
{{CompatGeckoDesktop(29.0)}} by default
{{CompatNo}} 19 {{CompatNo}}
Feature Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile Chrome for Android
Basic support {{CompatNo}} {{CompatGeckoMobile(24.0)}} as Future
{{CompatGeckoMobile(25.0)}} as Promise behind a flag[1]
{{CompatGeckoMobile(29.0)}} by default
{{CompatNo}} {{CompatNo}} {{CompatNo}} 32

[1] Gecko 24 has an experimental implementation of Promise, under the initial name of Future. It got 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.

See also

Revision Source

<p>{{SeeCompatTable}}</p>
<p>The <code><strong>Promise</strong></code> 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 <em>promise</em> of having a value at some point in the future.</p>
<p>A pending&nbsp;promise can become either <em>fulfilled</em> with a value, or <em>rejected</em> with a reason. When either of these happens, the associated handlers queued up by a promise's <code>then</code> 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.)</p>
<p>As the <code>Promise.prototype.then</code> and <code>Promise.prototype.catch</code> methods return promises, they can be chained—an operation called <em>composition</em>.</p>
<h2 id="Methods">Methods</h2>
<dl>
 <dt>
  <code>Promise.prototype.then(onFulfilled, onRejected)</code></dt>
 <dd>
  Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler.</dd>
 <dt>
  <code>Promise.prototype.catch(onRejected)</code></dt>
 <dd>
  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.</dd>
</dl>
<h2 id="Static_methods">Static methods</h2>
<dl>
 <dt>
  <code>Promise.resolve(value)</code></dt>
 <dd>
  Returns a <code>Promise</code> object that is resolved with the given value. If the value is a thenable (i.e. has a <code>then</code> method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the value.</dd>
</dl>
<dl>
 <dt>
  <code>Promise.reject(reason)</code></dt>
 <dd>
  Returns a <code>Promise</code> object that is rejected with the given reason.</dd>
</dl>
<dl>
 <dt>
  <code>Promise.all(iterable)</code></dt>
 <dd>
  Returns a promise that resolves when all of the promises in iterable have resolved. The result is passed an array of values from all the promises. If something passed in the iterable array is not a promise, it's converted to one by Promise.cast. If any of the passed in promises rejects, the <code>all</code> Promise immediately rejects with the value of the promise that rejected, discarding all the other promises whether or not they have resolved.
  <pre class="brush: js">
var p = new Promise(function(resolve, reject) { resolve(3); });
Promise.all([true, p]).then(function(values) {
  // values == [ true, 3 ]
});</pre>
 </dd>
 <dt>
  <code>Promise.race(iterable)</code></dt>
 <dd>
  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.</dd>
 <dd>
  <pre class="brush: js">
var p1 = new Promise(function(resolve, reject) { setTimeout(resolve, 500, "one"); });
var p2 = new Promise(function(resolve, reject) { setTimeout(resolve, 100, "two"); });

Promise.race([p1, p2]).then(function(value) {
  // value === "two"
});

<span style="line-height: normal;">var p3 = new Promise(function(resolve, reject) { setTimeout(resolve, 100, "three"); });
</span><span style="line-height: normal;">var p4 = new Promise(function(resolve, reject) { setTimeout(reject, 500, "four"); });

</span><span style="line-height: normal;">Promise.race([p3, p4]).then(function(value) {
</span><span style="line-height: normal;">  // value === "three"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</span><span style="line-height: normal;">}, function(reason) {
</span><span style="line-height: normal;">  // Not called
</span><span style="line-height: normal;">});

</span><span style="line-height: normal;">var p5 = new Promise(function(resolve, reject) { setTimeout(resolve, 500, "five"); });
</span><span style="line-height: normal;">var p6 = new Promise(function(resolve, reject) { setTimeout(reject, 100, "six"); });

</span><span style="line-height: normal;">Promise.race([p5, p6]).then(function(value) {
</span><span style="line-height: normal;">  // Not called &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</span><span style="line-height: normal;">}, function(reason) {
</span><span style="line-height: normal;">  // reason === "six"
</span><span style="line-height: normal;">});</span>
</pre>
 </dd>
</dl>
<h2 id="Example">Example</h2>
<pre class="brush: html" style="display:none;">
&lt;button id="btn"&gt;Make a promise!&lt;/button&gt;
&lt;div id="log"&gt;&lt;/div&gt;
</pre>
<p>This small example shows the mechanism of a <code>Promise</code>. The <code>testPromise()</code> method is called each time the {{HTMLElement("button")}} is clicked. It creates a promise that will resolve, using <code>window.setTimeout</code>, to the string <code>'result'</code> after <code>1s to 3s</code> (random).</p>
<p>The fulfillment of the promise is simply logged, via a fulfill callback set using <code>p1.then</code>. A few logs shows how the synchronous part of the method is decoupled of the asynchronous completion of the promise.</p>
<pre class="brush: js">
var promiseCount = 0;
function testPromise() {
  var thisPromiseCount = ++promiseCount;

  var log = document.getElementById('log');
  log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Started (&lt;small&gt;Sync code started&lt;/small&gt;)&lt;br/&gt;');

  var p1 = new Promise(               /* We make a new promise: we promise the string 'result' (after waiting 3s) */
    function(resolve, reject) {       /* The resolver function is called with the ability to resolve or reject the promise */
      log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Promise started (&lt;small&gt;Async code started&lt;/small&gt;)&lt;br/&gt;');
      window.setTimeout(              /* This only is an example to create asynchronism */
        function() {
          resolve(thisPromiseCount); /* We fulfill the promise ! */
        }, Math.random() * 2000 + 1000);
    });

  p1.then(                            /* We define what to do when the promise is fulfilled */
    function(val) {                   /* Just log the message and a value */
      log.insertAdjacentHTML('beforeend', val + ') Promise fulfilled (&lt;small&gt;Async code terminated&lt;/small&gt;)&lt;br/&gt;');
    });

  log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Promise made (&lt;small&gt;Sync code terminated&lt;/small&gt;)&lt;br/&gt;');
}
</pre>
<pre class="brush:js" style="display:none">
if ("Promise" in window) {
  btn = document.getElementById("btn");
   btn.addEventListener("click",testPromise);
}
else {
  log = document.getElementById('log');
  log.innerHTML = "Live example not available as your browser doesn't support the Promise interface.";
}
</pre>
<p>This example is executed when clicking the button. You need a browser supporting <code>Promise</code>. 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.</p>
<p>{{EmbedLiveSample("Example", "500", "300")}}</p>
<h2 id="Specification">Specification</h2>
<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td><a href="https://github.com/domenic/promises-unwrapping">domenic/promises-unwrapping</a></td>
   <td>Draft</td>
   <td>Initial work is taking place here</td>
  </tr>
  <tr>
   <td>ES6</td>
   <td>Draft</td>
   <td>Eventually it will be transferred to the full ES6 draft</td>
  </tr>
 </tbody>
</table>
<h2 id="Browser_compatibility">Browser compatibility</h2>
<p>{{CompatibilityTable}}</p>
<div id="compat-desktop">
 <table class="compat-table">
  <tbody>
   <tr>
    <th>Feature</th>
    <th>Chrome</th>
    <th>Firefox (Gecko)</th>
    <th>Internet Explorer</th>
    <th>Opera</th>
    <th>Safari</th>
   </tr>
   <tr>
    <td>Basic support</td>
    <td>32</td>
    <td>{{CompatGeckoDesktop(24.0)}} as <code>Future</code><br />
     {{CompatGeckoDesktop(25.0)}} as <code>Promise</code> behind a flag[1]<br />
     {{CompatGeckoDesktop(29.0)}} by default</td>
    <td>{{CompatNo}}</td>
    <td>19</td>
    <td>{{CompatNo}}</td>
   </tr>
  </tbody>
 </table>
</div>
<div id="compat-mobile">
 <table class="compat-table">
  <tbody>
   <tr>
    <th>Feature</th>
    <th>Android</th>
    <th>Firefox Mobile (Gecko)</th>
    <th>IE Mobile</th>
    <th>Opera Mobile</th>
    <th>Safari Mobile</th>
    <th>Chrome for Android</th>
   </tr>
   <tr>
    <td>Basic support</td>
    <td>{{CompatNo}}</td>
    <td>{{CompatGeckoMobile(24.0)}} as <code>Future</code><br />
     {{CompatGeckoMobile(25.0)}} as <code>Promise</code> behind a flag[1]<br />
     {{CompatGeckoMobile(29.0)}} by default</td>
    <td>{{CompatNo}}</td>
    <td>{{CompatNo}}</td>
    <td>{{CompatNo}}</td>
    <td>32</td>
   </tr>
  </tbody>
 </table>
</div>
<p>[1] Gecko 24 has an experimental implementation of <code>Promise</code>, under the initial name of <code>Future</code>. It got renamed to its final name in Gecko 25, but disabled by default behind the flag <code>dom.promise.enabled</code>. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=918806">Bug 918806</a> enabled Promises by default in Gecko 29.</p>
<h2 id="See_also">See also</h2>
<ul>
 <li><a href="http://www.html5rocks.com/en/tutorials/es6/promises/" title="/en-US/docs/Web/API/Guide/Using_DOM_Promises">JavaScript Promises: There and Back Again</a></li>
 <li><a href="http://promisesaplus.com/">Promises/A+ specification&nbsp;</a></li>
</ul>
Revert to this revision