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);