1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/lib/sdk/core/promise.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,117 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.7 + */ 1.8 + 1.9 +'use strict'; 1.10 + 1.11 +/* 1.12 + * Uses `Promise.jsm` as a core implementation, with additional sugar 1.13 + * from previous implementation, with inspiration from `Q` and `when` 1.14 + * 1.15 + * https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm 1.16 + * https://github.com/cujojs/when 1.17 + * https://github.com/kriskowal/q 1.18 + */ 1.19 +const PROMISE_URI = 'resource://gre/modules/Promise.jsm'; 1.20 + 1.21 +getEnvironment.call(this, function ({ require, exports, module, Cu }) { 1.22 + 1.23 +const { defer, resolve, all, reject, race } = Cu.import(PROMISE_URI, {}).Promise; 1.24 + 1.25 +module.metadata = { 1.26 + 'stability': 'unstable' 1.27 +}; 1.28 + 1.29 +let promised = (function() { 1.30 + // Note: Define shortcuts and utility functions here in order to avoid 1.31 + // slower property accesses and unnecessary closure creations on each 1.32 + // call of this popular function. 1.33 + 1.34 + var call = Function.call; 1.35 + var concat = Array.prototype.concat; 1.36 + 1.37 + // Utility function that does following: 1.38 + // execute([ f, self, args...]) => f.apply(self, args) 1.39 + function execute (args) call.apply(call, args) 1.40 + 1.41 + // Utility function that takes promise of `a` array and maybe promise `b` 1.42 + // as arguments and returns promise for `a.concat(b)`. 1.43 + function promisedConcat(promises, unknown) { 1.44 + return promises.then(function (values) { 1.45 + return resolve(unknown) 1.46 + .then(function (value) values.concat([value])); 1.47 + }); 1.48 + } 1.49 + 1.50 + return function promised(f, prototype) { 1.51 + /** 1.52 + Returns a wrapped `f`, which when called returns a promise that resolves to 1.53 + `f(...)` passing all the given arguments to it, which by the way may be 1.54 + promises. Optionally second `prototype` argument may be provided to be used 1.55 + a prototype for a returned promise. 1.56 + 1.57 + ## Example 1.58 + 1.59 + var promise = promised(Array)(1, promise(2), promise(3)) 1.60 + promise.then(console.log) // => [ 1, 2, 3 ] 1.61 + **/ 1.62 + 1.63 + return function promised() { 1.64 + // create array of [ f, this, args... ] 1.65 + return concat.apply([ f, this ], arguments). 1.66 + // reduce it via `promisedConcat` to get promised array of fulfillments 1.67 + reduce(promisedConcat, resolve([], prototype)). 1.68 + // finally map that to promise of `f.apply(this, args...)` 1.69 + then(execute); 1.70 + }; 1.71 + }; 1.72 +})(); 1.73 + 1.74 +exports.promised = promised; 1.75 +exports.all = all; 1.76 +exports.defer = defer; 1.77 +exports.resolve = resolve; 1.78 +exports.reject = reject; 1.79 +exports.race = race; 1.80 +exports.Promise = Promise; 1.81 + 1.82 +}); 1.83 + 1.84 +function getEnvironment (callback) { 1.85 + let Cu, _exports, _module, _require; 1.86 + 1.87 + // CommonJS / SDK 1.88 + if (typeof(require) === 'function') { 1.89 + Cu = require('chrome').Cu; 1.90 + _exports = exports; 1.91 + _module = module; 1.92 + _require = require; 1.93 + } 1.94 + // JSM 1.95 + else if (String(this).indexOf('BackstagePass') >= 0) { 1.96 + Cu = this['Components'].utils; 1.97 + _exports = this.Promise = {}; 1.98 + _module = { uri: __URI__, id: 'promise/core' }; 1.99 + _require = uri => { 1.100 + let imports = {}; 1.101 + Cu.import(uri, imports); 1.102 + return imports; 1.103 + }; 1.104 + this.EXPORTED_SYMBOLS = ['Promise']; 1.105 + // mozIJSSubScriptLoader.loadSubscript 1.106 + } else if (~String(this).indexOf('Sandbox')) { 1.107 + Cu = this['Components'].utils; 1.108 + _exports = this; 1.109 + _module = { id: 'promise/core' }; 1.110 + _require = uri => {}; 1.111 + } 1.112 + 1.113 + callback({ 1.114 + Cu: Cu, 1.115 + exports: _exports, 1.116 + module: _module, 1.117 + require: _require 1.118 + }); 1.119 +} 1.120 +