toolkit/modules/Promise.jsm

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/modules/Promise.jsm	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,101 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +"use strict";
    1.11 +
    1.12 +this.EXPORTED_SYMBOLS = [
    1.13 +  "Promise"
    1.14 +];
    1.15 +
    1.16 +/**
    1.17 + * This module implements the "promise" construct, according to the
    1.18 + * "Promises/A+" proposal as known in April 2013, documented here:
    1.19 + *
    1.20 + * <http://promises-aplus.github.com/promises-spec/>
    1.21 + *
    1.22 + * A promise is an object representing a value that may not be available yet.
    1.23 + * Internally, a promise can be in one of three states:
    1.24 + *
    1.25 + * - Pending, when the final value is not available yet.  This is the only state
    1.26 + *   that may transition to one of the other two states.
    1.27 + *
    1.28 + * - Resolved, when and if the final value becomes available.  A resolution
    1.29 + *   value becomes permanently associated with the promise.  This may be any
    1.30 + *   value, including "undefined".
    1.31 + *
    1.32 + * - Rejected, if an error prevented the final value from being determined.  A
    1.33 + *   rejection reason becomes permanently associated with the promise.  This may
    1.34 + *   be any value, including "undefined", though it is generally an Error
    1.35 + *   object, like in exception handling.
    1.36 + *
    1.37 + * A reference to an existing promise may be received by different means, for
    1.38 + * example as the return value of a call into an asynchronous API.  In this
    1.39 + * case, the state of the promise can be observed but not directly controlled.
    1.40 + *
    1.41 + * To observe the state of a promise, its "then" method must be used.  This
    1.42 + * method registers callback functions that are called as soon as the promise is
    1.43 + * either resolved or rejected.  The method returns a new promise, that in turn
    1.44 + * is resolved or rejected depending on the state of the original promise and on
    1.45 + * the behavior of the callbacks.  For example, unhandled exceptions in the
    1.46 + * callbacks cause the new promise to be rejected, even if the original promise
    1.47 + * is resolved.  See the documentation of the "then" method for details.
    1.48 + *
    1.49 + * Promises may also be created using the "Promise.defer" function, the main
    1.50 + * entry point of this module.  The function, along with the new promise,
    1.51 + * returns separate methods to change its state to be resolved or rejected.
    1.52 + * See the documentation of the "Deferred" prototype for details.
    1.53 + *
    1.54 + * -----------------------------------------------------------------------------
    1.55 + *
    1.56 + * Cu.import("resource://gre/modules/Promise.jsm");
    1.57 + *
    1.58 + * // This function creates and returns a new promise.
    1.59 + * function promiseValueAfterTimeout(aValue, aTimeout)
    1.60 + * {
    1.61 + *   let deferred = Promise.defer();
    1.62 + *
    1.63 + *   try {
    1.64 + *     // An asynchronous operation will trigger the resolution of the promise.
    1.65 + *     // In this example, we don't have a callback that triggers a rejection.
    1.66 + *     do_timeout(aTimeout, function () {
    1.67 + *       deferred.resolve(aValue);
    1.68 + *     });
    1.69 + *   } catch (ex) {
    1.70 + *     // Generally, functions returning promises propagate exceptions through
    1.71 + *     // the returned promise, though they may also choose to fail early.
    1.72 + *     deferred.reject(ex);
    1.73 + *   }
    1.74 + *
    1.75 + *   // We don't return the deferred to the caller, but only the contained
    1.76 + *   // promise, so that the caller cannot accidentally change its state.
    1.77 + *   return deferred.promise;
    1.78 + * }
    1.79 + *
    1.80 + * // This code uses the promise returned be the function above.
    1.81 + * let promise = promiseValueAfterTimeout("Value", 1000);
    1.82 + *
    1.83 + * let newPromise = promise.then(function onResolve(aValue) {
    1.84 + *   do_print("Resolved with this value: " + aValue);
    1.85 + * }, function onReject(aReason) {
    1.86 + *   do_print("Rejected with this reason: " + aReason);
    1.87 + * });
    1.88 + *
    1.89 + * // Unexpected errors should always be reported at the end of a promise chain.
    1.90 + * newPromise.then(null, Components.utils.reportError);
    1.91 + *
    1.92 + * -----------------------------------------------------------------------------
    1.93 + */
    1.94 +
    1.95 +// These constants must be defined on the "this" object for them to be visible
    1.96 +// by subscripts in B2G, since "this" does not match the global scope.
    1.97 +this.Cc = Components.classes;
    1.98 +this.Ci = Components.interfaces;
    1.99 +this.Cu = Components.utils;
   1.100 +this.Cr = Components.results;
   1.101 +
   1.102 +this.Cc["@mozilla.org/moz/jssubscript-loader;1"]
   1.103 +    .getService(this.Ci.mozIJSSubScriptLoader)
   1.104 +    .loadSubScript("resource://gre/modules/Promise-backend.js", this);

mercurial