addon-sdk/source/lib/sdk/core/promise.js

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:bb7eeb25596e
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 */
5
6 'use strict';
7
8 /*
9 * Uses `Promise.jsm` as a core implementation, with additional sugar
10 * from previous implementation, with inspiration from `Q` and `when`
11 *
12 * https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm
13 * https://github.com/cujojs/when
14 * https://github.com/kriskowal/q
15 */
16 const PROMISE_URI = 'resource://gre/modules/Promise.jsm';
17
18 getEnvironment.call(this, function ({ require, exports, module, Cu }) {
19
20 const { defer, resolve, all, reject, race } = Cu.import(PROMISE_URI, {}).Promise;
21
22 module.metadata = {
23 'stability': 'unstable'
24 };
25
26 let promised = (function() {
27 // Note: Define shortcuts and utility functions here in order to avoid
28 // slower property accesses and unnecessary closure creations on each
29 // call of this popular function.
30
31 var call = Function.call;
32 var concat = Array.prototype.concat;
33
34 // Utility function that does following:
35 // execute([ f, self, args...]) => f.apply(self, args)
36 function execute (args) call.apply(call, args)
37
38 // Utility function that takes promise of `a` array and maybe promise `b`
39 // as arguments and returns promise for `a.concat(b)`.
40 function promisedConcat(promises, unknown) {
41 return promises.then(function (values) {
42 return resolve(unknown)
43 .then(function (value) values.concat([value]));
44 });
45 }
46
47 return function promised(f, prototype) {
48 /**
49 Returns a wrapped `f`, which when called returns a promise that resolves to
50 `f(...)` passing all the given arguments to it, which by the way may be
51 promises. Optionally second `prototype` argument may be provided to be used
52 a prototype for a returned promise.
53
54 ## Example
55
56 var promise = promised(Array)(1, promise(2), promise(3))
57 promise.then(console.log) // => [ 1, 2, 3 ]
58 **/
59
60 return function promised() {
61 // create array of [ f, this, args... ]
62 return concat.apply([ f, this ], arguments).
63 // reduce it via `promisedConcat` to get promised array of fulfillments
64 reduce(promisedConcat, resolve([], prototype)).
65 // finally map that to promise of `f.apply(this, args...)`
66 then(execute);
67 };
68 };
69 })();
70
71 exports.promised = promised;
72 exports.all = all;
73 exports.defer = defer;
74 exports.resolve = resolve;
75 exports.reject = reject;
76 exports.race = race;
77 exports.Promise = Promise;
78
79 });
80
81 function getEnvironment (callback) {
82 let Cu, _exports, _module, _require;
83
84 // CommonJS / SDK
85 if (typeof(require) === 'function') {
86 Cu = require('chrome').Cu;
87 _exports = exports;
88 _module = module;
89 _require = require;
90 }
91 // JSM
92 else if (String(this).indexOf('BackstagePass') >= 0) {
93 Cu = this['Components'].utils;
94 _exports = this.Promise = {};
95 _module = { uri: __URI__, id: 'promise/core' };
96 _require = uri => {
97 let imports = {};
98 Cu.import(uri, imports);
99 return imports;
100 };
101 this.EXPORTED_SYMBOLS = ['Promise'];
102 // mozIJSSubScriptLoader.loadSubscript
103 } else if (~String(this).indexOf('Sandbox')) {
104 Cu = this['Components'].utils;
105 _exports = this;
106 _module = { id: 'promise/core' };
107 _require = uri => {};
108 }
109
110 callback({
111 Cu: Cu,
112 exports: _exports,
113 module: _module,
114 require: _require
115 });
116 }
117

mercurial