The Promise.jsm JavaScript code module implements the Promises/A+ proposal as known in April 2013. To use it, you first need to import the code module into your JavaScript scope:


Note: A preliminary promise module is also available starting from Gecko 17, though it didn't conform to the Promises/A+ proposal until Gecko 25:

Components.utils.import("resource://gre/modules/commonjs/promise/core.js");     // Gecko 17 to 20
Components.utils.import("resource://gre/modules/commonjs/sdk/core/promise.js"); // Gecko 21 to 24

This implementation also includes helper functions that are specific to the Add-on SDK. While you may still import this module from the above paths, the recommended way for loading it is through the Add-on SDK loader.


For an introduction to promises, you may start from the Add-on SDK documentation, keeping in mind that only the core subset is implemented in this module.

A promise is an object representing a value that may not be available yet. Internally, a promise can be in one of three states:

  • Pending, when the final value is not available yet. This is the only state that may transition to one of the other two states.
  • Fulfilled, when and if the final value becomes available. A fulfillment value becomes permanently associated with the promise. This may be any value, including undefined.
  • Rejected, if an error prevented the final value from being determined. A rejection reason becomes permanently associated with the promise. This may be any value, including undefined, though it is generally an Error object, like in exception handling.

A reference to an existing promise may be received by different means, for example as the return value of a call into an asynchronous API. In this case, the state of the promise can be observed but not directly controlled.

To observe the state of a promise, its then method must be used. This method registers callback functions that are called as soon as the promise is either fulfilled or rejected. The method returns a new promise, that in turn is fulfilled or rejected depending on the state of the original promise and on the behavior of the callbacks. For example, unhandled exceptions in the callbacks cause the new promise to be rejected, even if the original promise is fulfilled. See the documentation of the then method for details.

Promises may also be created using the Promise.defer() function, the main entry point of this module. The function, along with the new promise, returns separate methods to resolve or reject the promise. See the documentation of the Deferred object for details.

Method overview

Deferred defer();
Promise resolve([optional] aValue);
Promise reject([optional] aReason);



Creates a new pending promise and provides methods to resolve or reject it.

Deferred defer();


Return value

A new object, containing the new promise in the promise property, and the methods to change its state in the resolve and reject properties. See the Deferred documentation for details.


Creates a new promise fulfilled with the specified value, or propagates the state of an existing promise.

Promise resolve(
aValue Optional
If this value is not a promise, including undefined, it becomes the fulfillment value of the returned promise. If this value is a promise, then the returned promise will be resolved with the value, i.e. it will eventually assume the same state as the provided promise.
Return value

A promise that can be pending, fulfilled, or rejected.


Creates a new promise rejected with the specified reason.

Promise reject(
aReason Optional

The rejection reason for the returned promise. Although the reason can be undefined, it is generally an Error object, like in exception handling.

Note: This argument should not be a promise. Specifying a rejected promise would make the rejection reason equal to the rejected promise itself, and not its rejection reason.
Return value

A rejected promise.



// This function creates and returns a new promise.
function promiseValueAfterTimeout(aValue, aTimeout)
  let deferred = Promise.defer();

  try {
    // An asynchronous operation will trigger the resolution of the promise.
    // In this example, we don't have a callback that triggers a rejection.
    setTimeout(function () {
    }, aTimeout);
  } catch (ex) {
    // Generally, functions returning promises propagate exceptions through
    // the returned promise, though they may also choose to fail early.

  // We don't return the deferred to the caller, but only the contained
  // promise, so that the caller cannot accidentally change its state.
  return deferred.promise;

// This code uses the promise returned be the function above.
let promise = promiseValueAfterTimeout("Value", 1000);

let newPromise = promise.then(function onFulfill(aValue) {
  console.log("Fulfilled with this value: " + aValue);
}, function onReject(aReason) {
  console.log("Rejected with this reason: " + aReason);

// Unexpected errors should always be reported at the end of a promise chain.
newPromise.then(null, Components.utils.reportError);
Note: More examples for consuming promises are available in the Promise object documentation.

The case of unhandled rejections

One of the difficult problems with promises is locating uncaught rejections.

Warning: When consuming promises, you should always handle or report errors (rejection reasons). See handling errors and common pitfalls.

Rejection handlers provide information about the exact error time and location, but the handlers may sometimes be forgotten. Consider the following cases:

function f() {
  return Promise.reject(new Error("BOOM!")); // If nobody catches the error, how will it be reported?

function g() {
  return Promise.resolve().then(function() {
    throw new Error("BOOM!"); // If nobody catches the error, how will it be reported?

function h() {
  Promise.reject(new Error("BOOM!"); // Oops, we forgot to return the promise, nobody can catch it!

We adopt the following strategy: if a promise is rejected at the time of its garbage-collection and if the promise is at the end of a promise chain (i.e. thatPromise.then has never been called), then we print a warning.

Note: This warning is generated some time after the error occurred, and may provide less information about the error location. It generally indicates the need to insert a proper error handler. When a proper rejection handler is used, it effectively replaces this delayed reporting.
let deferred = Promise.defer();
let p = deferred.promise.then();
deferred.reject(new Error("I am an uncaught error"));
deferred = null;
p = null;

In this snippet, since deferred.promise is not the last in the chain, no error will be reported for that promise. However, since p is the last promise in the chain, the error will be reported for p.

Note that this may, in some cases, cause an error to be reported more than once. For instance, consider:

let deferred = Promise.defer();
let p1 = deferred.promise.then();
let p2 = deferred.promise.then();
deferred.reject(new Error("I am an uncaught error"));
p1 = p2 = deferred = null;

In this snippet, the error is reported both at p1 and at p2.

See also


 此页面的贡献者: wbamberg
 最后编辑者: wbamberg,