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

changeset 0
6474c204b198
     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 +

mercurial