"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/q/q.js" (11 Apr 2017, 59053 Bytes) of package /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // vim:ts=4:sts=4:sw=4:
    2 /*!
    3  *
    4  * Copyright 2009-2012 Kris Kowal under the terms of the MIT
    5  * license found at http://github.com/kriskowal/q/raw/master/LICENSE
    6  *
    7  * With parts by Tyler Close
    8  * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
    9  * at http://www.opensource.org/licenses/mit-license.html
   10  * Forked at ref_send.js version: 2009-05-11
   11  *
   12  * With parts by Mark Miller
   13  * Copyright (C) 2011 Google Inc.
   14  *
   15  * Licensed under the Apache License, Version 2.0 (the "License");
   16  * you may not use this file except in compliance with the License.
   17  * You may obtain a copy of the License at
   18  *
   19  * http://www.apache.org/licenses/LICENSE-2.0
   20  *
   21  * Unless required by applicable law or agreed to in writing, software
   22  * distributed under the License is distributed on an "AS IS" BASIS,
   23  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   24  * See the License for the specific language governing permissions and
   25  * limitations under the License.
   26  *
   27  */
   28 
   29 (function (definition) {
   30     // Turn off strict mode for this function so we can assign to global.Q
   31     /* jshint strict: false */
   32 
   33     // This file will function properly as a <script> tag, or a module
   34     // using CommonJS and NodeJS or RequireJS module formats.  In
   35     // Common/Node/RequireJS, the module exports the Q API and when
   36     // executed as a simple <script>, it creates a Q global instead.
   37 
   38     // Montage Require
   39     if (typeof bootstrap === "function") {
   40         bootstrap("promise", definition);
   41 
   42     // CommonJS
   43     } else if (typeof exports === "object") {
   44         module.exports = definition();
   45 
   46     // RequireJS
   47     } else if (typeof define === "function" && define.amd) {
   48         define(definition);
   49 
   50     // SES (Secure EcmaScript)
   51     } else if (typeof ses !== "undefined") {
   52         if (!ses.ok()) {
   53             return;
   54         } else {
   55             ses.makeQ = definition;
   56         }
   57 
   58     // <script>
   59     } else {
   60         Q = definition();
   61     }
   62 
   63 })(function () {
   64 "use strict";
   65 
   66 var hasStacks = false;
   67 try {
   68     throw new Error();
   69 } catch (e) {
   70     hasStacks = !!e.stack;
   71 }
   72 
   73 // All code after this point will be filtered from stack traces reported
   74 // by Q.
   75 var qStartingLine = captureLine();
   76 var qFileName;
   77 
   78 // shims
   79 
   80 // used for fallback in "allResolved"
   81 var noop = function () {};
   82 
   83 // Use the fastest possible means to execute a task in a future turn
   84 // of the event loop.
   85 var nextTick =(function () {
   86     // linked list of tasks (single, with head node)
   87     var head = {task: void 0, next: null};
   88     var tail = head;
   89     var flushing = false;
   90     var requestTick = void 0;
   91     var isNodeJS = false;
   92 
   93     function flush() {
   94         /* jshint loopfunc: true */
   95 
   96         while (head.next) {
   97             head = head.next;
   98             var task = head.task;
   99             head.task = void 0;
  100             var domain = head.domain;
  101 
  102             if (domain) {
  103                 head.domain = void 0;
  104                 domain.enter();
  105             }
  106 
  107             try {
  108                 task();
  109 
  110             } catch (e) {
  111                 if (isNodeJS) {
  112                     // In node, uncaught exceptions are considered fatal errors.
  113                     // Re-throw them synchronously to interrupt flushing!
  114 
  115                     // Ensure continuation if the uncaught exception is suppressed
  116                     // listening "uncaughtException" events (as domains does).
  117                     // Continue in next event to avoid tick recursion.
  118                     if (domain) {
  119                         domain.exit();
  120                     }
  121                     setTimeout(flush, 0);
  122                     if (domain) {
  123                         domain.enter();
  124                     }
  125 
  126                     throw e;
  127 
  128                 } else {
  129                     // In browsers, uncaught exceptions are not fatal.
  130                     // Re-throw them asynchronously to avoid slow-downs.
  131                     setTimeout(function() {
  132                        throw e;
  133                     }, 0);
  134                 }
  135             }
  136 
  137             if (domain) {
  138                 domain.exit();
  139             }
  140         }
  141 
  142         flushing = false;
  143     }
  144 
  145     nextTick = function (task) {
  146         tail = tail.next = {
  147             task: task,
  148             domain: isNodeJS && process.domain,
  149             next: null
  150         };
  151 
  152         if (!flushing) {
  153             flushing = true;
  154             requestTick();
  155         }
  156     };
  157 
  158     if (typeof process !== "undefined" && process.nextTick) {
  159         // Node.js before 0.9. Note that some fake-Node environments, like the
  160         // Mocha test runner, introduce a `process` global without a `nextTick`.
  161         isNodeJS = true;
  162 
  163         requestTick = function () {
  164             process.nextTick(flush);
  165         };
  166 
  167     } else if (typeof setImmediate === "function") {
  168         // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
  169         if (typeof window !== "undefined") {
  170             requestTick = setImmediate.bind(window, flush);
  171         } else {
  172             requestTick = function () {
  173                 setImmediate(flush);
  174             };
  175         }
  176 
  177     } else if (typeof MessageChannel !== "undefined") {
  178         // modern browsers
  179         // http://www.nonblocking.io/2011/06/windownexttick.html
  180         var channel = new MessageChannel();
  181         // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
  182         // working message ports the first time a page loads.
  183         channel.port1.onmessage = function () {
  184             requestTick = requestPortTick;
  185             channel.port1.onmessage = flush;
  186             flush();
  187         };
  188         var requestPortTick = function () {
  189             // Opera requires us to provide a message payload, regardless of
  190             // whether we use it.
  191             channel.port2.postMessage(0);
  192         };
  193         requestTick = function () {
  194             setTimeout(flush, 0);
  195             requestPortTick();
  196         };
  197 
  198     } else {
  199         // old browsers
  200         requestTick = function () {
  201             setTimeout(flush, 0);
  202         };
  203     }
  204 
  205     return nextTick;
  206 })();
  207 
  208 // Attempt to make generics safe in the face of downstream
  209 // modifications.
  210 // There is no situation where this is necessary.
  211 // If you need a security guarantee, these primordials need to be
  212 // deeply frozen anyway, and if you don’t need a security guarantee,
  213 // this is just plain paranoid.
  214 // However, this does have the nice side-effect of reducing the size
  215 // of the code by reducing x.call() to merely x(), eliminating many
  216 // hard-to-minify characters.
  217 // See Mark Miller’s explanation of what this does.
  218 // http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
  219 var call = Function.call;
  220 function uncurryThis(f) {
  221     return function () {
  222         return call.apply(f, arguments);
  223     };
  224 }
  225 // This is equivalent, but slower:
  226 // uncurryThis = Function_bind.bind(Function_bind.call);
  227 // http://jsperf.com/uncurrythis
  228 
  229 var array_slice = uncurryThis(Array.prototype.slice);
  230 
  231 var array_reduce = uncurryThis(
  232     Array.prototype.reduce || function (callback, basis) {
  233         var index = 0,
  234             length = this.length;
  235         // concerning the initial value, if one is not provided
  236         if (arguments.length === 1) {
  237             // seek to the first value in the array, accounting
  238             // for the possibility that is is a sparse array
  239             do {
  240                 if (index in this) {
  241                     basis = this[index++];
  242                     break;
  243                 }
  244                 if (++index >= length) {
  245                     throw new TypeError();
  246                 }
  247             } while (1);
  248         }
  249         // reduce
  250         for (; index < length; index++) {
  251             // account for the possibility that the array is sparse
  252             if (index in this) {
  253                 basis = callback(basis, this[index], index);
  254             }
  255         }
  256         return basis;
  257     }
  258 );
  259 
  260 var array_indexOf = uncurryThis(
  261     Array.prototype.indexOf || function (value) {
  262         // not a very good shim, but good enough for our one use of it
  263         for (var i = 0; i < this.length; i++) {
  264             if (this[i] === value) {
  265                 return i;
  266             }
  267         }
  268         return -1;
  269     }
  270 );
  271 
  272 var array_map = uncurryThis(
  273     Array.prototype.map || function (callback, thisp) {
  274         var self = this;
  275         var collect = [];
  276         array_reduce(self, function (undefined, value, index) {
  277             collect.push(callback.call(thisp, value, index, self));
  278         }, void 0);
  279         return collect;
  280     }
  281 );
  282 
  283 var object_create = Object.create || function (prototype) {
  284     function Type() { }
  285     Type.prototype = prototype;
  286     return new Type();
  287 };
  288 
  289 var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
  290 
  291 var object_keys = Object.keys || function (object) {
  292     var keys = [];
  293     for (var key in object) {
  294         if (object_hasOwnProperty(object, key)) {
  295             keys.push(key);
  296         }
  297     }
  298     return keys;
  299 };
  300 
  301 var object_toString = uncurryThis(Object.prototype.toString);
  302 
  303 function isObject(value) {
  304     return value === Object(value);
  305 }
  306 
  307 // generator related shims
  308 
  309 // FIXME: Remove this function once ES6 generators are in SpiderMonkey.
  310 function isStopIteration(exception) {
  311     return (
  312         object_toString(exception) === "[object StopIteration]" ||
  313         exception instanceof QReturnValue
  314     );
  315 }
  316 
  317 // FIXME: Remove this helper and Q.return once ES6 generators are in
  318 // SpiderMonkey.
  319 var QReturnValue;
  320 if (typeof ReturnValue !== "undefined") {
  321     QReturnValue = ReturnValue;
  322 } else {
  323     QReturnValue = function (value) {
  324         this.value = value;
  325     };
  326 }
  327 
  328 // Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only
  329 // engine that has a deployed base of browsers that support generators.
  330 // However, SM's generators use the Python-inspired semantics of
  331 // outdated ES6 drafts.  We would like to support ES6, but we'd also
  332 // like to make it possible to use generators in deployed browsers, so
  333 // we also support Python-style generators.  At some point we can remove
  334 // this block.
  335 var hasES6Generators;
  336 try {
  337     /* jshint evil: true, nonew: false */
  338     new Function("(function* (){ yield 1; })");
  339     hasES6Generators = true;
  340 } catch (e) {
  341     hasES6Generators = false;
  342 }
  343 
  344 // long stack traces
  345 
  346 var STACK_JUMP_SEPARATOR = "From previous event:";
  347 
  348 function makeStackTraceLong(error, promise) {
  349     // If possible, transform the error stack trace by removing Node and Q
  350     // cruft, then concatenating with the stack trace of `promise`. See #57.
  351     if (hasStacks &&
  352         promise.stack &&
  353         typeof error === "object" &&
  354         error !== null &&
  355         error.stack &&
  356         error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
  357     ) {
  358         var stacks = [];
  359         for (var p = promise; !!p; p = p.source) {
  360             if (p.stack) {
  361                 stacks.unshift(p.stack);
  362             }
  363         }
  364         stacks.unshift(error.stack);
  365 
  366         var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");
  367         error.stack = filterStackString(concatedStacks);
  368     }
  369 }
  370 
  371 function filterStackString(stackString) {
  372     var lines = stackString.split("\n");
  373     var desiredLines = [];
  374     for (var i = 0; i < lines.length; ++i) {
  375         var line = lines[i];
  376 
  377         if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
  378             desiredLines.push(line);
  379         }
  380     }
  381     return desiredLines.join("\n");
  382 }
  383 
  384 function isNodeFrame(stackLine) {
  385     return stackLine.indexOf("(module.js:") !== -1 ||
  386            stackLine.indexOf("(node.js:") !== -1;
  387 }
  388 
  389 function getFileNameAndLineNumber(stackLine) {
  390     // Named functions: "at functionName (filename:lineNumber:columnNumber)"
  391     // In IE10 function name can have spaces ("Anonymous function") O_o
  392     var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
  393     if (attempt1) {
  394         return [attempt1[1], Number(attempt1[2])];
  395     }
  396 
  397     // Anonymous functions: "at filename:lineNumber:columnNumber"
  398     var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
  399     if (attempt2) {
  400         return [attempt2[1], Number(attempt2[2])];
  401     }
  402 
  403     // Firefox style: "function@filename:lineNumber or @filename:lineNumber"
  404     var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
  405     if (attempt3) {
  406         return [attempt3[1], Number(attempt3[2])];
  407     }
  408 }
  409 
  410 function isInternalFrame(stackLine) {
  411     var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
  412 
  413     if (!fileNameAndLineNumber) {
  414         return false;
  415     }
  416 
  417     var fileName = fileNameAndLineNumber[0];
  418     var lineNumber = fileNameAndLineNumber[1];
  419 
  420     return fileName === qFileName &&
  421         lineNumber >= qStartingLine &&
  422         lineNumber <= qEndingLine;
  423 }
  424 
  425 // discover own file name and line number range for filtering stack
  426 // traces
  427 function captureLine() {
  428     if (!hasStacks) {
  429         return;
  430     }
  431 
  432     try {
  433         throw new Error();
  434     } catch (e) {
  435         var lines = e.stack.split("\n");
  436         var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
  437         var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
  438         if (!fileNameAndLineNumber) {
  439             return;
  440         }
  441 
  442         qFileName = fileNameAndLineNumber[0];
  443         return fileNameAndLineNumber[1];
  444     }
  445 }
  446 
  447 function deprecate(callback, name, alternative) {
  448     return function () {
  449         if (typeof console !== "undefined" &&
  450             typeof console.warn === "function") {
  451             console.warn(name + " is deprecated, use " + alternative +
  452                          " instead.", new Error("").stack);
  453         }
  454         return callback.apply(callback, arguments);
  455     };
  456 }
  457 
  458 // end of shims
  459 // beginning of real work
  460 
  461 /**
  462  * Constructs a promise for an immediate reference, passes promises through, or
  463  * coerces promises from different systems.
  464  * @param value immediate reference or promise
  465  */
  466 function Q(value) {
  467     // If the object is already a Promise, return it directly.  This enables
  468     // the resolve function to both be used to created references from objects,
  469     // but to tolerably coerce non-promises to promises.
  470     if (isPromise(value)) {
  471         return value;
  472     }
  473 
  474     // assimilate thenables
  475     if (isPromiseAlike(value)) {
  476         return coerce(value);
  477     } else {
  478         return fulfill(value);
  479     }
  480 }
  481 Q.resolve = Q;
  482 
  483 /**
  484  * Performs a task in a future turn of the event loop.
  485  * @param {Function} task
  486  */
  487 Q.nextTick = nextTick;
  488 
  489 /**
  490  * Controls whether or not long stack traces will be on
  491  */
  492 Q.longStackSupport = false;
  493 
  494 /**
  495  * Constructs a {promise, resolve, reject} object.
  496  *
  497  * `resolve` is a callback to invoke with a more resolved value for the
  498  * promise. To fulfill the promise, invoke `resolve` with any value that is
  499  * not a thenable. To reject the promise, invoke `resolve` with a rejected
  500  * thenable, or invoke `reject` with the reason directly. To resolve the
  501  * promise to another thenable, thus putting it in the same state, invoke
  502  * `resolve` with that other thenable.
  503  */
  504 Q.defer = defer;
  505 function defer() {
  506     // if "messages" is an "Array", that indicates that the promise has not yet
  507     // been resolved.  If it is "undefined", it has been resolved.  Each
  508     // element of the messages array is itself an array of complete arguments to
  509     // forward to the resolved promise.  We coerce the resolution value to a
  510     // promise using the `resolve` function because it handles both fully
  511     // non-thenable values and other thenables gracefully.
  512     var messages = [], progressListeners = [], resolvedPromise;
  513 
  514     var deferred = object_create(defer.prototype);
  515     var promise = object_create(Promise.prototype);
  516 
  517     promise.promiseDispatch = function (resolve, op, operands) {
  518         var args = array_slice(arguments);
  519         if (messages) {
  520             messages.push(args);
  521             if (op === "when" && operands[1]) { // progress operand
  522                 progressListeners.push(operands[1]);
  523             }
  524         } else {
  525             nextTick(function () {
  526                 resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
  527             });
  528         }
  529     };
  530 
  531     // XXX deprecated
  532     promise.valueOf = deprecate(function () {
  533         if (messages) {
  534             return promise;
  535         }
  536         var nearerValue = nearer(resolvedPromise);
  537         if (isPromise(nearerValue)) {
  538             resolvedPromise = nearerValue; // shorten chain
  539         }
  540         return nearerValue;
  541     }, "valueOf", "inspect");
  542 
  543     promise.inspect = function () {
  544         if (!resolvedPromise) {
  545             return { state: "pending" };
  546         }
  547         return resolvedPromise.inspect();
  548     };
  549 
  550     if (Q.longStackSupport && hasStacks) {
  551         try {
  552             throw new Error();
  553         } catch (e) {
  554             // NOTE: don't try to use `Error.captureStackTrace` or transfer the
  555             // accessor around; that causes memory leaks as per GH-111. Just
  556             // reify the stack trace as a string ASAP.
  557             //
  558             // At the same time, cut off the first line; it's always just
  559             // "[object Promise]\n", as per the `toString`.
  560             promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
  561         }
  562     }
  563 
  564     // NOTE: we do the checks for `resolvedPromise` in each method, instead of
  565     // consolidating them into `become`, since otherwise we'd create new
  566     // promises with the lines `become(whatever(value))`. See e.g. GH-252.
  567 
  568     function become(newPromise) {
  569         resolvedPromise = newPromise;
  570         promise.source = newPromise;
  571 
  572         array_reduce(messages, function (undefined, message) {
  573             nextTick(function () {
  574                 newPromise.promiseDispatch.apply(newPromise, message);
  575             });
  576         }, void 0);
  577 
  578         messages = void 0;
  579         progressListeners = void 0;
  580     }
  581 
  582     deferred.promise = promise;
  583     deferred.resolve = function (value) {
  584         if (resolvedPromise) {
  585             return;
  586         }
  587 
  588         become(Q(value));
  589     };
  590 
  591     deferred.fulfill = function (value) {
  592         if (resolvedPromise) {
  593             return;
  594         }
  595 
  596         become(fulfill(value));
  597     };
  598     deferred.reject = function (reason) {
  599         if (resolvedPromise) {
  600             return;
  601         }
  602 
  603         become(reject(reason));
  604     };
  605     deferred.notify = function (progress) {
  606         if (resolvedPromise) {
  607             return;
  608         }
  609 
  610         array_reduce(progressListeners, function (undefined, progressListener) {
  611             nextTick(function () {
  612                 progressListener(progress);
  613             });
  614         }, void 0);
  615     };
  616 
  617     return deferred;
  618 }
  619 
  620 /**
  621  * Creates a Node-style callback that will resolve or reject the deferred
  622  * promise.
  623  * @returns a nodeback
  624  */
  625 defer.prototype.makeNodeResolver = function () {
  626     var self = this;
  627     return function (error, value) {
  628         if (error) {
  629             self.reject(error);
  630         } else if (arguments.length > 2) {
  631             self.resolve(array_slice(arguments, 1));
  632         } else {
  633             self.resolve(value);
  634         }
  635     };
  636 };
  637 
  638 /**
  639  * @param resolver {Function} a function that returns nothing and accepts
  640  * the resolve, reject, and notify functions for a deferred.
  641  * @returns a promise that may be resolved with the given resolve and reject
  642  * functions, or rejected by a thrown exception in resolver
  643  */
  644 Q.promise = promise;
  645 function promise(resolver) {
  646     if (typeof resolver !== "function") {
  647         throw new TypeError("resolver must be a function.");
  648     }
  649     var deferred = defer();
  650     try {
  651         resolver(deferred.resolve, deferred.reject, deferred.notify);
  652     } catch (reason) {
  653         deferred.reject(reason);
  654     }
  655     return deferred.promise;
  656 }
  657 
  658 // XXX experimental.  This method is a way to denote that a local value is
  659 // serializable and should be immediately dispatched to a remote upon request,
  660 // instead of passing a reference.
  661 Q.passByCopy = function (object) {
  662     //freeze(object);
  663     //passByCopies.set(object, true);
  664     return object;
  665 };
  666 
  667 Promise.prototype.passByCopy = function () {
  668     //freeze(object);
  669     //passByCopies.set(object, true);
  670     return this;
  671 };
  672 
  673 /**
  674  * If two promises eventually fulfill to the same value, promises that value,
  675  * but otherwise rejects.
  676  * @param x {Any*}
  677  * @param y {Any*}
  678  * @returns {Any*} a promise for x and y if they are the same, but a rejection
  679  * otherwise.
  680  *
  681  */
  682 Q.join = function (x, y) {
  683     return Q(x).join(y);
  684 };
  685 
  686 Promise.prototype.join = function (that) {
  687     return Q([this, that]).spread(function (x, y) {
  688         if (x === y) {
  689             // TODO: "===" should be Object.is or equiv
  690             return x;
  691         } else {
  692             throw new Error("Can't join: not the same: " + x + " " + y);
  693         }
  694     });
  695 };
  696 
  697 /**
  698  * Returns a promise for the first of an array of promises to become fulfilled.
  699  * @param answers {Array[Any*]} promises to race
  700  * @returns {Any*} the first promise to be fulfilled
  701  */
  702 Q.race = race;
  703 function race(answerPs) {
  704     return promise(function(resolve, reject) {
  705         // Switch to this once we can assume at least ES5
  706         // answerPs.forEach(function(answerP) {
  707         //     Q(answerP).then(resolve, reject);
  708         // });
  709         // Use this in the meantime
  710         for (var i = 0, len = answerPs.length; i < len; i++) {
  711             Q(answerPs[i]).then(resolve, reject);
  712         }
  713     });
  714 }
  715 
  716 Promise.prototype.race = function () {
  717     return this.then(Q.race);
  718 };
  719 
  720 /**
  721  * Constructs a Promise with a promise descriptor object and optional fallback
  722  * function.  The descriptor contains methods like when(rejected), get(name),
  723  * set(name, value), post(name, args), and delete(name), which all
  724  * return either a value, a promise for a value, or a rejection.  The fallback
  725  * accepts the operation name, a resolver, and any further arguments that would
  726  * have been forwarded to the appropriate method above had a method been
  727  * provided with the proper name.  The API makes no guarantees about the nature
  728  * of the returned object, apart from that it is usable whereever promises are
  729  * bought and sold.
  730  */
  731 Q.makePromise = Promise;
  732 function Promise(descriptor, fallback, inspect) {
  733     if (fallback === void 0) {
  734         fallback = function (op) {
  735             return reject(new Error(
  736                 "Promise does not support operation: " + op
  737             ));
  738         };
  739     }
  740     if (inspect === void 0) {
  741         inspect = function () {
  742             return {state: "unknown"};
  743         };
  744     }
  745 
  746     var promise = object_create(Promise.prototype);
  747 
  748     promise.promiseDispatch = function (resolve, op, args) {
  749         var result;
  750         try {
  751             if (descriptor[op]) {
  752                 result = descriptor[op].apply(promise, args);
  753             } else {
  754                 result = fallback.call(promise, op, args);
  755             }
  756         } catch (exception) {
  757             result = reject(exception);
  758         }
  759         if (resolve) {
  760             resolve(result);
  761         }
  762     };
  763 
  764     promise.inspect = inspect;
  765 
  766     // XXX deprecated `valueOf` and `exception` support
  767     if (inspect) {
  768         var inspected = inspect();
  769         if (inspected.state === "rejected") {
  770             promise.exception = inspected.reason;
  771         }
  772 
  773         promise.valueOf = deprecate(function () {
  774             var inspected = inspect();
  775             if (inspected.state === "pending" ||
  776                 inspected.state === "rejected") {
  777                 return promise;
  778             }
  779             return inspected.value;
  780         });
  781     }
  782 
  783     return promise;
  784 }
  785 
  786 Promise.prototype.toString = function () {
  787     return "[object Promise]";
  788 };
  789 
  790 Promise.prototype.then = function (fulfilled, rejected, progressed) {
  791     var self = this;
  792     var deferred = defer();
  793     var done = false;   // ensure the untrusted promise makes at most a
  794                         // single call to one of the callbacks
  795 
  796     function _fulfilled(value) {
  797         try {
  798             return typeof fulfilled === "function" ? fulfilled(value) : value;
  799         } catch (exception) {
  800             return reject(exception);
  801         }
  802     }
  803 
  804     function _rejected(exception) {
  805         if (typeof rejected === "function") {
  806             makeStackTraceLong(exception, self);
  807             try {
  808                 return rejected(exception);
  809             } catch (newException) {
  810                 return reject(newException);
  811             }
  812         }
  813         return reject(exception);
  814     }
  815 
  816     function _progressed(value) {
  817         return typeof progressed === "function" ? progressed(value) : value;
  818     }
  819 
  820     nextTick(function () {
  821         self.promiseDispatch(function (value) {
  822             if (done) {
  823                 return;
  824             }
  825             done = true;
  826 
  827             deferred.resolve(_fulfilled(value));
  828         }, "when", [function (exception) {
  829             if (done) {
  830                 return;
  831             }
  832             done = true;
  833 
  834             deferred.resolve(_rejected(exception));
  835         }]);
  836     });
  837 
  838     // Progress propagator need to be attached in the current tick.
  839     self.promiseDispatch(void 0, "when", [void 0, function (value) {
  840         var newValue;
  841         var threw = false;
  842         try {
  843             newValue = _progressed(value);
  844         } catch (e) {
  845             threw = true;
  846             if (Q.onerror) {
  847                 Q.onerror(e);
  848             } else {
  849                 throw e;
  850             }
  851         }
  852 
  853         if (!threw) {
  854             deferred.notify(newValue);
  855         }
  856     }]);
  857 
  858     return deferred.promise;
  859 };
  860 
  861 /**
  862  * Registers an observer on a promise.
  863  *
  864  * Guarantees:
  865  *
  866  * 1. that fulfilled and rejected will be called only once.
  867  * 2. that either the fulfilled callback or the rejected callback will be
  868  *    called, but not both.
  869  * 3. that fulfilled and rejected will not be called in this turn.
  870  *
  871  * @param value      promise or immediate reference to observe
  872  * @param fulfilled  function to be called with the fulfilled value
  873  * @param rejected   function to be called with the rejection exception
  874  * @param progressed function to be called on any progress notifications
  875  * @return promise for the return value from the invoked callback
  876  */
  877 Q.when = when;
  878 function when(value, fulfilled, rejected, progressed) {
  879     return Q(value).then(fulfilled, rejected, progressed);
  880 }
  881 
  882 Promise.prototype.thenResolve = function (value) {
  883     return this.then(function () { return value; });
  884 };
  885 
  886 Q.thenResolve = function (promise, value) {
  887     return Q(promise).thenResolve(value);
  888 };
  889 
  890 Promise.prototype.thenReject = function (reason) {
  891     return this.then(function () { throw reason; });
  892 };
  893 
  894 Q.thenReject = function (promise, reason) {
  895     return Q(promise).thenReject(reason);
  896 };
  897 
  898 /**
  899  * If an object is not a promise, it is as "near" as possible.
  900  * If a promise is rejected, it is as "near" as possible too.
  901  * If it’s a fulfilled promise, the fulfillment value is nearer.
  902  * If it’s a deferred promise and the deferred has been resolved, the
  903  * resolution is "nearer".
  904  * @param object
  905  * @returns most resolved (nearest) form of the object
  906  */
  907 
  908 // XXX should we re-do this?
  909 Q.nearer = nearer;
  910 function nearer(value) {
  911     if (isPromise(value)) {
  912         var inspected = value.inspect();
  913         if (inspected.state === "fulfilled") {
  914             return inspected.value;
  915         }
  916     }
  917     return value;
  918 }
  919 
  920 /**
  921  * @returns whether the given object is a promise.
  922  * Otherwise it is a fulfilled value.
  923  */
  924 Q.isPromise = isPromise;
  925 function isPromise(object) {
  926     return isObject(object) &&
  927         typeof object.promiseDispatch === "function" &&
  928         typeof object.inspect === "function";
  929 }
  930 
  931 Q.isPromiseAlike = isPromiseAlike;
  932 function isPromiseAlike(object) {
  933     return isObject(object) && typeof object.then === "function";
  934 }
  935 
  936 /**
  937  * @returns whether the given object is a pending promise, meaning not
  938  * fulfilled or rejected.
  939  */
  940 Q.isPending = isPending;
  941 function isPending(object) {
  942     return isPromise(object) && object.inspect().state === "pending";
  943 }
  944 
  945 Promise.prototype.isPending = function () {
  946     return this.inspect().state === "pending";
  947 };
  948 
  949 /**
  950  * @returns whether the given object is a value or fulfilled
  951  * promise.
  952  */
  953 Q.isFulfilled = isFulfilled;
  954 function isFulfilled(object) {
  955     return !isPromise(object) || object.inspect().state === "fulfilled";
  956 }
  957 
  958 Promise.prototype.isFulfilled = function () {
  959     return this.inspect().state === "fulfilled";
  960 };
  961 
  962 /**
  963  * @returns whether the given object is a rejected promise.
  964  */
  965 Q.isRejected = isRejected;
  966 function isRejected(object) {
  967     return isPromise(object) && object.inspect().state === "rejected";
  968 }
  969 
  970 Promise.prototype.isRejected = function () {
  971     return this.inspect().state === "rejected";
  972 };
  973 
  974 //// BEGIN UNHANDLED REJECTION TRACKING
  975 
  976 // This promise library consumes exceptions thrown in handlers so they can be
  977 // handled by a subsequent promise.  The exceptions get added to this array when
  978 // they are created, and removed when they are handled.  Note that in ES6 or
  979 // shimmed environments, this would naturally be a `Set`.
  980 var unhandledReasons = [];
  981 var unhandledRejections = [];
  982 var unhandledReasonsDisplayed = false;
  983 var trackUnhandledRejections = true;
  984 function displayUnhandledReasons() {
  985     if (
  986         !unhandledReasonsDisplayed &&
  987         typeof window !== "undefined" &&
  988         !window.Touch &&
  989         window.console
  990     ) {
  991         console.warn("[Q] Unhandled rejection reasons (should be empty):",
  992                      unhandledReasons);
  993     }
  994 
  995     unhandledReasonsDisplayed = true;
  996 }
  997 
  998 function logUnhandledReasons() {
  999     for (var i = 0; i < unhandledReasons.length; i++) {
 1000         var reason = unhandledReasons[i];
 1001         console.warn("Unhandled rejection reason:", reason);
 1002     }
 1003 }
 1004 
 1005 function resetUnhandledRejections() {
 1006     unhandledReasons.length = 0;
 1007     unhandledRejections.length = 0;
 1008     unhandledReasonsDisplayed = false;
 1009 
 1010     if (!trackUnhandledRejections) {
 1011         trackUnhandledRejections = true;
 1012 
 1013         // Show unhandled rejection reasons if Node exits without handling an
 1014         // outstanding rejection.  (Note that Browserify presently produces a
 1015         // `process` global without the `EventEmitter` `on` method.)
 1016         if (typeof process !== "undefined" && process.on) {
 1017             process.on("exit", logUnhandledReasons);
 1018         }
 1019     }
 1020 }
 1021 
 1022 function trackRejection(promise, reason) {
 1023     if (!trackUnhandledRejections) {
 1024         return;
 1025     }
 1026 
 1027     unhandledRejections.push(promise);
 1028     if (reason && typeof reason.stack !== "undefined") {
 1029         unhandledReasons.push(reason.stack);
 1030     } else {
 1031         unhandledReasons.push("(no stack) " + reason);
 1032     }
 1033     displayUnhandledReasons();
 1034 }
 1035 
 1036 function untrackRejection(promise) {
 1037     if (!trackUnhandledRejections) {
 1038         return;
 1039     }
 1040 
 1041     var at = array_indexOf(unhandledRejections, promise);
 1042     if (at !== -1) {
 1043         unhandledRejections.splice(at, 1);
 1044         unhandledReasons.splice(at, 1);
 1045     }
 1046 }
 1047 
 1048 Q.resetUnhandledRejections = resetUnhandledRejections;
 1049 
 1050 Q.getUnhandledReasons = function () {
 1051     // Make a copy so that consumers can't interfere with our internal state.
 1052     return unhandledReasons.slice();
 1053 };
 1054 
 1055 Q.stopUnhandledRejectionTracking = function () {
 1056     resetUnhandledRejections();
 1057     if (typeof process !== "undefined" && process.on) {
 1058         process.removeListener("exit", logUnhandledReasons);
 1059     }
 1060     trackUnhandledRejections = false;
 1061 };
 1062 
 1063 resetUnhandledRejections();
 1064 
 1065 //// END UNHANDLED REJECTION TRACKING
 1066 
 1067 /**
 1068  * Constructs a rejected promise.
 1069  * @param reason value describing the failure
 1070  */
 1071 Q.reject = reject;
 1072 function reject(reason) {
 1073     var rejection = Promise({
 1074         "when": function (rejected) {
 1075             // note that the error has been handled
 1076             if (rejected) {
 1077                 untrackRejection(this);
 1078             }
 1079             return rejected ? rejected(reason) : this;
 1080         }
 1081     }, function fallback() {
 1082         return this;
 1083     }, function inspect() {
 1084         return { state: "rejected", reason: reason };
 1085     });
 1086 
 1087     // Note that the reason has not been handled.
 1088     trackRejection(rejection, reason);
 1089 
 1090     return rejection;
 1091 }
 1092 
 1093 /**
 1094  * Constructs a fulfilled promise for an immediate reference.
 1095  * @param value immediate reference
 1096  */
 1097 Q.fulfill = fulfill;
 1098 function fulfill(value) {
 1099     return Promise({
 1100         "when": function () {
 1101             return value;
 1102         },
 1103         "get": function (name) {
 1104             return value[name];
 1105         },
 1106         "set": function (name, rhs) {
 1107             value[name] = rhs;
 1108         },
 1109         "delete": function (name) {
 1110             delete value[name];
 1111         },
 1112         "post": function (name, args) {
 1113             // Mark Miller proposes that post with no name should apply a
 1114             // promised function.
 1115             if (name === null || name === void 0) {
 1116                 return value.apply(void 0, args);
 1117             } else {
 1118                 return value[name].apply(value, args);
 1119             }
 1120         },
 1121         "apply": function (thisp, args) {
 1122             return value.apply(thisp, args);
 1123         },
 1124         "keys": function () {
 1125             return object_keys(value);
 1126         }
 1127     }, void 0, function inspect() {
 1128         return { state: "fulfilled", value: value };
 1129     });
 1130 }
 1131 
 1132 /**
 1133  * Converts thenables to Q promises.
 1134  * @param promise thenable promise
 1135  * @returns a Q promise
 1136  */
 1137 function coerce(promise) {
 1138     var deferred = defer();
 1139     nextTick(function () {
 1140         try {
 1141             promise.then(deferred.resolve, deferred.reject, deferred.notify);
 1142         } catch (exception) {
 1143             deferred.reject(exception);
 1144         }
 1145     });
 1146     return deferred.promise;
 1147 }
 1148 
 1149 /**
 1150  * Annotates an object such that it will never be
 1151  * transferred away from this process over any promise
 1152  * communication channel.
 1153  * @param object
 1154  * @returns promise a wrapping of that object that
 1155  * additionally responds to the "isDef" message
 1156  * without a rejection.
 1157  */
 1158 Q.master = master;
 1159 function master(object) {
 1160     return Promise({
 1161         "isDef": function () {}
 1162     }, function fallback(op, args) {
 1163         return dispatch(object, op, args);
 1164     }, function () {
 1165         return Q(object).inspect();
 1166     });
 1167 }
 1168 
 1169 /**
 1170  * Spreads the values of a promised array of arguments into the
 1171  * fulfillment callback.
 1172  * @param fulfilled callback that receives variadic arguments from the
 1173  * promised array
 1174  * @param rejected callback that receives the exception if the promise
 1175  * is rejected.
 1176  * @returns a promise for the return value or thrown exception of
 1177  * either callback.
 1178  */
 1179 Q.spread = spread;
 1180 function spread(value, fulfilled, rejected) {
 1181     return Q(value).spread(fulfilled, rejected);
 1182 }
 1183 
 1184 Promise.prototype.spread = function (fulfilled, rejected) {
 1185     return this.all().then(function (array) {
 1186         return fulfilled.apply(void 0, array);
 1187     }, rejected);
 1188 };
 1189 
 1190 /**
 1191  * The async function is a decorator for generator functions, turning
 1192  * them into asynchronous generators.  Although generators are only part
 1193  * of the newest ECMAScript 6 drafts, this code does not cause syntax
 1194  * errors in older engines.  This code should continue to work and will
 1195  * in fact improve over time as the language improves.
 1196  *
 1197  * ES6 generators are currently part of V8 version 3.19 with the
 1198  * --harmony-generators runtime flag enabled.  SpiderMonkey has had them
 1199  * for longer, but under an older Python-inspired form.  This function
 1200  * works on both kinds of generators.
 1201  *
 1202  * Decorates a generator function such that:
 1203  *  - it may yield promises
 1204  *  - execution will continue when that promise is fulfilled
 1205  *  - the value of the yield expression will be the fulfilled value
 1206  *  - it returns a promise for the return value (when the generator
 1207  *    stops iterating)
 1208  *  - the decorated function returns a promise for the return value
 1209  *    of the generator or the first rejected promise among those
 1210  *    yielded.
 1211  *  - if an error is thrown in the generator, it propagates through
 1212  *    every following yield until it is caught, or until it escapes
 1213  *    the generator function altogether, and is translated into a
 1214  *    rejection for the promise returned by the decorated generator.
 1215  */
 1216 Q.async = async;
 1217 function async(makeGenerator) {
 1218     return function () {
 1219         // when verb is "send", arg is a value
 1220         // when verb is "throw", arg is an exception
 1221         function continuer(verb, arg) {
 1222             var result;
 1223             if (hasES6Generators) {
 1224                 try {
 1225                     result = generator[verb](arg);
 1226                 } catch (exception) {
 1227                     return reject(exception);
 1228                 }
 1229                 if (result.done) {
 1230                     return result.value;
 1231                 } else {
 1232                     return when(result.value, callback, errback);
 1233                 }
 1234             } else {
 1235                 // FIXME: Remove this case when SM does ES6 generators.
 1236                 try {
 1237                     result = generator[verb](arg);
 1238                 } catch (exception) {
 1239                     if (isStopIteration(exception)) {
 1240                         return exception.value;
 1241                     } else {
 1242                         return reject(exception);
 1243                     }
 1244                 }
 1245                 return when(result, callback, errback);
 1246             }
 1247         }
 1248         var generator = makeGenerator.apply(this, arguments);
 1249         var callback = continuer.bind(continuer, "next");
 1250         var errback = continuer.bind(continuer, "throw");
 1251         return callback();
 1252     };
 1253 }
 1254 
 1255 /**
 1256  * The spawn function is a small wrapper around async that immediately
 1257  * calls the generator and also ends the promise chain, so that any
 1258  * unhandled errors are thrown instead of forwarded to the error
 1259  * handler. This is useful because it's extremely common to run
 1260  * generators at the top-level to work with libraries.
 1261  */
 1262 Q.spawn = spawn;
 1263 function spawn(makeGenerator) {
 1264     Q.done(Q.async(makeGenerator)());
 1265 }
 1266 
 1267 // FIXME: Remove this interface once ES6 generators are in SpiderMonkey.
 1268 /**
 1269  * Throws a ReturnValue exception to stop an asynchronous generator.
 1270  *
 1271  * This interface is a stop-gap measure to support generator return
 1272  * values in older Firefox/SpiderMonkey.  In browsers that support ES6
 1273  * generators like Chromium 29, just use "return" in your generator
 1274  * functions.
 1275  *
 1276  * @param value the return value for the surrounding generator
 1277  * @throws ReturnValue exception with the value.
 1278  * @example
 1279  * // ES6 style
 1280  * Q.async(function* () {
 1281  *      var foo = yield getFooPromise();
 1282  *      var bar = yield getBarPromise();
 1283  *      return foo + bar;
 1284  * })
 1285  * // Older SpiderMonkey style
 1286  * Q.async(function () {
 1287  *      var foo = yield getFooPromise();
 1288  *      var bar = yield getBarPromise();
 1289  *      Q.return(foo + bar);
 1290  * })
 1291  */
 1292 Q["return"] = _return;
 1293 function _return(value) {
 1294     throw new QReturnValue(value);
 1295 }
 1296 
 1297 /**
 1298  * The promised function decorator ensures that any promise arguments
 1299  * are settled and passed as values (`this` is also settled and passed
 1300  * as a value).  It will also ensure that the result of a function is
 1301  * always a promise.
 1302  *
 1303  * @example
 1304  * var add = Q.promised(function (a, b) {
 1305  *     return a + b;
 1306  * });
 1307  * add(Q(a), Q(B));
 1308  *
 1309  * @param {function} callback The function to decorate
 1310  * @returns {function} a function that has been decorated.
 1311  */
 1312 Q.promised = promised;
 1313 function promised(callback) {
 1314     return function () {
 1315         return spread([this, all(arguments)], function (self, args) {
 1316             return callback.apply(self, args);
 1317         });
 1318     };
 1319 }
 1320 
 1321 /**
 1322  * sends a message to a value in a future turn
 1323  * @param object* the recipient
 1324  * @param op the name of the message operation, e.g., "when",
 1325  * @param args further arguments to be forwarded to the operation
 1326  * @returns result {Promise} a promise for the result of the operation
 1327  */
 1328 Q.dispatch = dispatch;
 1329 function dispatch(object, op, args) {
 1330     return Q(object).dispatch(op, args);
 1331 }
 1332 
 1333 Promise.prototype.dispatch = function (op, args) {
 1334     var self = this;
 1335     var deferred = defer();
 1336     nextTick(function () {
 1337         self.promiseDispatch(deferred.resolve, op, args);
 1338     });
 1339     return deferred.promise;
 1340 };
 1341 
 1342 /**
 1343  * Gets the value of a property in a future turn.
 1344  * @param object    promise or immediate reference for target object
 1345  * @param name      name of property to get
 1346  * @return promise for the property value
 1347  */
 1348 Q.get = function (object, key) {
 1349     return Q(object).dispatch("get", [key]);
 1350 };
 1351 
 1352 Promise.prototype.get = function (key) {
 1353     return this.dispatch("get", [key]);
 1354 };
 1355 
 1356 /**
 1357  * Sets the value of a property in a future turn.
 1358  * @param object    promise or immediate reference for object object
 1359  * @param name      name of property to set
 1360  * @param value     new value of property
 1361  * @return promise for the return value
 1362  */
 1363 Q.set = function (object, key, value) {
 1364     return Q(object).dispatch("set", [key, value]);
 1365 };
 1366 
 1367 Promise.prototype.set = function (key, value) {
 1368     return this.dispatch("set", [key, value]);
 1369 };
 1370 
 1371 /**
 1372  * Deletes a property in a future turn.
 1373  * @param object    promise or immediate reference for target object
 1374  * @param name      name of property to delete
 1375  * @return promise for the return value
 1376  */
 1377 Q.del = // XXX legacy
 1378 Q["delete"] = function (object, key) {
 1379     return Q(object).dispatch("delete", [key]);
 1380 };
 1381 
 1382 Promise.prototype.del = // XXX legacy
 1383 Promise.prototype["delete"] = function (key) {
 1384     return this.dispatch("delete", [key]);
 1385 };
 1386 
 1387 /**
 1388  * Invokes a method in a future turn.
 1389  * @param object    promise or immediate reference for target object
 1390  * @param name      name of method to invoke
 1391  * @param value     a value to post, typically an array of
 1392  *                  invocation arguments for promises that
 1393  *                  are ultimately backed with `resolve` values,
 1394  *                  as opposed to those backed with URLs
 1395  *                  wherein the posted value can be any
 1396  *                  JSON serializable object.
 1397  * @return promise for the return value
 1398  */
 1399 // bound locally because it is used by other methods
 1400 Q.mapply = // XXX As proposed by "Redsandro"
 1401 Q.post = function (object, name, args) {
 1402     return Q(object).dispatch("post", [name, args]);
 1403 };
 1404 
 1405 Promise.prototype.mapply = // XXX As proposed by "Redsandro"
 1406 Promise.prototype.post = function (name, args) {
 1407     return this.dispatch("post", [name, args]);
 1408 };
 1409 
 1410 /**
 1411  * Invokes a method in a future turn.
 1412  * @param object    promise or immediate reference for target object
 1413  * @param name      name of method to invoke
 1414  * @param ...args   array of invocation arguments
 1415  * @return promise for the return value
 1416  */
 1417 Q.send = // XXX Mark Miller's proposed parlance
 1418 Q.mcall = // XXX As proposed by "Redsandro"
 1419 Q.invoke = function (object, name /*...args*/) {
 1420     return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);
 1421 };
 1422 
 1423 Promise.prototype.send = // XXX Mark Miller's proposed parlance
 1424 Promise.prototype.mcall = // XXX As proposed by "Redsandro"
 1425 Promise.prototype.invoke = function (name /*...args*/) {
 1426     return this.dispatch("post", [name, array_slice(arguments, 1)]);
 1427 };
 1428 
 1429 /**
 1430  * Applies the promised function in a future turn.
 1431  * @param object    promise or immediate reference for target function
 1432  * @param args      array of application arguments
 1433  */
 1434 Q.fapply = function (object, args) {
 1435     return Q(object).dispatch("apply", [void 0, args]);
 1436 };
 1437 
 1438 Promise.prototype.fapply = function (args) {
 1439     return this.dispatch("apply", [void 0, args]);
 1440 };
 1441 
 1442 /**
 1443  * Calls the promised function in a future turn.
 1444  * @param object    promise or immediate reference for target function
 1445  * @param ...args   array of application arguments
 1446  */
 1447 Q["try"] =
 1448 Q.fcall = function (object /* ...args*/) {
 1449     return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);
 1450 };
 1451 
 1452 Promise.prototype.fcall = function (/*...args*/) {
 1453     return this.dispatch("apply", [void 0, array_slice(arguments)]);
 1454 };
 1455 
 1456 /**
 1457  * Binds the promised function, transforming return values into a fulfilled
 1458  * promise and thrown errors into a rejected one.
 1459  * @param object    promise or immediate reference for target function
 1460  * @param ...args   array of application arguments
 1461  */
 1462 Q.fbind = function (object /*...args*/) {
 1463     var promise = Q(object);
 1464     var args = array_slice(arguments, 1);
 1465     return function fbound() {
 1466         return promise.dispatch("apply", [
 1467             this,
 1468             args.concat(array_slice(arguments))
 1469         ]);
 1470     };
 1471 };
 1472 Promise.prototype.fbind = function (/*...args*/) {
 1473     var promise = this;
 1474     var args = array_slice(arguments);
 1475     return function fbound() {
 1476         return promise.dispatch("apply", [
 1477             this,
 1478             args.concat(array_slice(arguments))
 1479         ]);
 1480     };
 1481 };
 1482 
 1483 /**
 1484  * Requests the names of the owned properties of a promised
 1485  * object in a future turn.
 1486  * @param object    promise or immediate reference for target object
 1487  * @return promise for the keys of the eventually settled object
 1488  */
 1489 Q.keys = function (object) {
 1490     return Q(object).dispatch("keys", []);
 1491 };
 1492 
 1493 Promise.prototype.keys = function () {
 1494     return this.dispatch("keys", []);
 1495 };
 1496 
 1497 /**
 1498  * Turns an array of promises into a promise for an array.  If any of
 1499  * the promises gets rejected, the whole array is rejected immediately.
 1500  * @param {Array*} an array (or promise for an array) of values (or
 1501  * promises for values)
 1502  * @returns a promise for an array of the corresponding values
 1503  */
 1504 // By Mark Miller
 1505 // http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled
 1506 Q.all = all;
 1507 function all(promises) {
 1508     return when(promises, function (promises) {
 1509         var countDown = 0;
 1510         var deferred = defer();
 1511         array_reduce(promises, function (undefined, promise, index) {
 1512             var snapshot;
 1513             if (
 1514                 isPromise(promise) &&
 1515                 (snapshot = promise.inspect()).state === "fulfilled"
 1516             ) {
 1517                 promises[index] = snapshot.value;
 1518             } else {
 1519                 ++countDown;
 1520                 when(
 1521                     promise,
 1522                     function (value) {
 1523                         promises[index] = value;
 1524                         if (--countDown === 0) {
 1525                             deferred.resolve(promises);
 1526                         }
 1527                     },
 1528                     deferred.reject,
 1529                     function (progress) {
 1530                         deferred.notify({ index: index, value: progress });
 1531                     }
 1532                 );
 1533             }
 1534         }, void 0);
 1535         if (countDown === 0) {
 1536             deferred.resolve(promises);
 1537         }
 1538         return deferred.promise;
 1539     });
 1540 }
 1541 
 1542 Promise.prototype.all = function () {
 1543     return all(this);
 1544 };
 1545 
 1546 /**
 1547  * Waits for all promises to be settled, either fulfilled or
 1548  * rejected.  This is distinct from `all` since that would stop
 1549  * waiting at the first rejection.  The promise returned by
 1550  * `allResolved` will never be rejected.
 1551  * @param promises a promise for an array (or an array) of promises
 1552  * (or values)
 1553  * @return a promise for an array of promises
 1554  */
 1555 Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");
 1556 function allResolved(promises) {
 1557     return when(promises, function (promises) {
 1558         promises = array_map(promises, Q);
 1559         return when(all(array_map(promises, function (promise) {
 1560             return when(promise, noop, noop);
 1561         })), function () {
 1562             return promises;
 1563         });
 1564     });
 1565 }
 1566 
 1567 Promise.prototype.allResolved = function () {
 1568     return allResolved(this);
 1569 };
 1570 
 1571 /**
 1572  * @see Promise#allSettled
 1573  */
 1574 Q.allSettled = allSettled;
 1575 function allSettled(promises) {
 1576     return Q(promises).allSettled();
 1577 }
 1578 
 1579 /**
 1580  * Turns an array of promises into a promise for an array of their states (as
 1581  * returned by `inspect`) when they have all settled.
 1582  * @param {Array[Any*]} values an array (or promise for an array) of values (or
 1583  * promises for values)
 1584  * @returns {Array[State]} an array of states for the respective values.
 1585  */
 1586 Promise.prototype.allSettled = function () {
 1587     return this.then(function (promises) {
 1588         return all(array_map(promises, function (promise) {
 1589             promise = Q(promise);
 1590             function regardless() {
 1591                 return promise.inspect();
 1592             }
 1593             return promise.then(regardless, regardless);
 1594         }));
 1595     });
 1596 };
 1597 
 1598 /**
 1599  * Captures the failure of a promise, giving an oportunity to recover
 1600  * with a callback.  If the given promise is fulfilled, the returned
 1601  * promise is fulfilled.
 1602  * @param {Any*} promise for something
 1603  * @param {Function} callback to fulfill the returned promise if the
 1604  * given promise is rejected
 1605  * @returns a promise for the return value of the callback
 1606  */
 1607 Q.fail = // XXX legacy
 1608 Q["catch"] = function (object, rejected) {
 1609     return Q(object).then(void 0, rejected);
 1610 };
 1611 
 1612 Promise.prototype.fail = // XXX legacy
 1613 Promise.prototype["catch"] = function (rejected) {
 1614     return this.then(void 0, rejected);
 1615 };
 1616 
 1617 /**
 1618  * Attaches a listener that can respond to progress notifications from a
 1619  * promise's originating deferred. This listener receives the exact arguments
 1620  * passed to ``deferred.notify``.
 1621  * @param {Any*} promise for something
 1622  * @param {Function} callback to receive any progress notifications
 1623  * @returns the given promise, unchanged
 1624  */
 1625 Q.progress = progress;
 1626 function progress(object, progressed) {
 1627     return Q(object).then(void 0, void 0, progressed);
 1628 }
 1629 
 1630 Promise.prototype.progress = function (progressed) {
 1631     return this.then(void 0, void 0, progressed);
 1632 };
 1633 
 1634 /**
 1635  * Provides an opportunity to observe the settling of a promise,
 1636  * regardless of whether the promise is fulfilled or rejected.  Forwards
 1637  * the resolution to the returned promise when the callback is done.
 1638  * The callback can return a promise to defer completion.
 1639  * @param {Any*} promise
 1640  * @param {Function} callback to observe the resolution of the given
 1641  * promise, takes no arguments.
 1642  * @returns a promise for the resolution of the given promise when
 1643  * ``fin`` is done.
 1644  */
 1645 Q.fin = // XXX legacy
 1646 Q["finally"] = function (object, callback) {
 1647     return Q(object)["finally"](callback);
 1648 };
 1649 
 1650 Promise.prototype.fin = // XXX legacy
 1651 Promise.prototype["finally"] = function (callback) {
 1652     callback = Q(callback);
 1653     return this.then(function (value) {
 1654         return callback.fcall().then(function () {
 1655             return value;
 1656         });
 1657     }, function (reason) {
 1658         // TODO attempt to recycle the rejection with "this".
 1659         return callback.fcall().then(function () {
 1660             throw reason;
 1661         });
 1662     });
 1663 };
 1664 
 1665 /**
 1666  * Terminates a chain of promises, forcing rejections to be
 1667  * thrown as exceptions.
 1668  * @param {Any*} promise at the end of a chain of promises
 1669  * @returns nothing
 1670  */
 1671 Q.done = function (object, fulfilled, rejected, progress) {
 1672     return Q(object).done(fulfilled, rejected, progress);
 1673 };
 1674 
 1675 Promise.prototype.done = function (fulfilled, rejected, progress) {
 1676     var onUnhandledError = function (error) {
 1677         // forward to a future turn so that ``when``
 1678         // does not catch it and turn it into a rejection.
 1679         nextTick(function () {
 1680             makeStackTraceLong(error, promise);
 1681             if (Q.onerror) {
 1682                 Q.onerror(error);
 1683             } else {
 1684                 throw error;
 1685             }
 1686         });
 1687     };
 1688 
 1689     // Avoid unnecessary `nextTick`ing via an unnecessary `when`.
 1690     var promise = fulfilled || rejected || progress ?
 1691         this.then(fulfilled, rejected, progress) :
 1692         this;
 1693 
 1694     if (typeof process === "object" && process && process.domain) {
 1695         onUnhandledError = process.domain.bind(onUnhandledError);
 1696     }
 1697 
 1698     promise.then(void 0, onUnhandledError);
 1699 };
 1700 
 1701 /**
 1702  * Causes a promise to be rejected if it does not get fulfilled before
 1703  * some milliseconds time out.
 1704  * @param {Any*} promise
 1705  * @param {Number} milliseconds timeout
 1706  * @param {String} custom error message (optional)
 1707  * @returns a promise for the resolution of the given promise if it is
 1708  * fulfilled before the timeout, otherwise rejected.
 1709  */
 1710 Q.timeout = function (object, ms, message) {
 1711     return Q(object).timeout(ms, message);
 1712 };
 1713 
 1714 Promise.prototype.timeout = function (ms, message) {
 1715     var deferred = defer();
 1716     var timeoutId = setTimeout(function () {
 1717         deferred.reject(new Error(message || "Timed out after " + ms + " ms"));
 1718     }, ms);
 1719 
 1720     this.then(function (value) {
 1721         clearTimeout(timeoutId);
 1722         deferred.resolve(value);
 1723     }, function (exception) {
 1724         clearTimeout(timeoutId);
 1725         deferred.reject(exception);
 1726     }, deferred.notify);
 1727 
 1728     return deferred.promise;
 1729 };
 1730 
 1731 /**
 1732  * Returns a promise for the given value (or promised value), some
 1733  * milliseconds after it resolved. Passes rejections immediately.
 1734  * @param {Any*} promise
 1735  * @param {Number} milliseconds
 1736  * @returns a promise for the resolution of the given promise after milliseconds
 1737  * time has elapsed since the resolution of the given promise.
 1738  * If the given promise rejects, that is passed immediately.
 1739  */
 1740 Q.delay = function (object, timeout) {
 1741     if (timeout === void 0) {
 1742         timeout = object;
 1743         object = void 0;
 1744     }
 1745     return Q(object).delay(timeout);
 1746 };
 1747 
 1748 Promise.prototype.delay = function (timeout) {
 1749     return this.then(function (value) {
 1750         var deferred = defer();
 1751         setTimeout(function () {
 1752             deferred.resolve(value);
 1753         }, timeout);
 1754         return deferred.promise;
 1755     });
 1756 };
 1757 
 1758 /**
 1759  * Passes a continuation to a Node function, which is called with the given
 1760  * arguments provided as an array, and returns a promise.
 1761  *
 1762  *      Q.nfapply(FS.readFile, [__filename])
 1763  *      .then(function (content) {
 1764  *      })
 1765  *
 1766  */
 1767 Q.nfapply = function (callback, args) {
 1768     return Q(callback).nfapply(args);
 1769 };
 1770 
 1771 Promise.prototype.nfapply = function (args) {
 1772     var deferred = defer();
 1773     var nodeArgs = array_slice(args);
 1774     nodeArgs.push(deferred.makeNodeResolver());
 1775     this.fapply(nodeArgs).fail(deferred.reject);
 1776     return deferred.promise;
 1777 };
 1778 
 1779 /**
 1780  * Passes a continuation to a Node function, which is called with the given
 1781  * arguments provided individually, and returns a promise.
 1782  * @example
 1783  * Q.nfcall(FS.readFile, __filename)
 1784  * .then(function (content) {
 1785  * })
 1786  *
 1787  */
 1788 Q.nfcall = function (callback /*...args*/) {
 1789     var args = array_slice(arguments, 1);
 1790     return Q(callback).nfapply(args);
 1791 };
 1792 
 1793 Promise.prototype.nfcall = function (/*...args*/) {
 1794     var nodeArgs = array_slice(arguments);
 1795     var deferred = defer();
 1796     nodeArgs.push(deferred.makeNodeResolver());
 1797     this.fapply(nodeArgs).fail(deferred.reject);
 1798     return deferred.promise;
 1799 };
 1800 
 1801 /**
 1802  * Wraps a NodeJS continuation passing function and returns an equivalent
 1803  * version that returns a promise.
 1804  * @example
 1805  * Q.nfbind(FS.readFile, __filename)("utf-8")
 1806  * .then(console.log)
 1807  * .done()
 1808  */
 1809 Q.nfbind =
 1810 Q.denodeify = function (callback /*...args*/) {
 1811     var baseArgs = array_slice(arguments, 1);
 1812     return function () {
 1813         var nodeArgs = baseArgs.concat(array_slice(arguments));
 1814         var deferred = defer();
 1815         nodeArgs.push(deferred.makeNodeResolver());
 1816         Q(callback).fapply(nodeArgs).fail(deferred.reject);
 1817         return deferred.promise;
 1818     };
 1819 };
 1820 
 1821 Promise.prototype.nfbind =
 1822 Promise.prototype.denodeify = function (/*...args*/) {
 1823     var args = array_slice(arguments);
 1824     args.unshift(this);
 1825     return Q.denodeify.apply(void 0, args);
 1826 };
 1827 
 1828 Q.nbind = function (callback, thisp /*...args*/) {
 1829     var baseArgs = array_slice(arguments, 2);
 1830     return function () {
 1831         var nodeArgs = baseArgs.concat(array_slice(arguments));
 1832         var deferred = defer();
 1833         nodeArgs.push(deferred.makeNodeResolver());
 1834         function bound() {
 1835             return callback.apply(thisp, arguments);
 1836         }
 1837         Q(bound).fapply(nodeArgs).fail(deferred.reject);
 1838         return deferred.promise;
 1839     };
 1840 };
 1841 
 1842 Promise.prototype.nbind = function (/*thisp, ...args*/) {
 1843     var args = array_slice(arguments, 0);
 1844     args.unshift(this);
 1845     return Q.nbind.apply(void 0, args);
 1846 };
 1847 
 1848 /**
 1849  * Calls a method of a Node-style object that accepts a Node-style
 1850  * callback with a given array of arguments, plus a provided callback.
 1851  * @param object an object that has the named method
 1852  * @param {String} name name of the method of object
 1853  * @param {Array} args arguments to pass to the method; the callback
 1854  * will be provided by Q and appended to these arguments.
 1855  * @returns a promise for the value or error
 1856  */
 1857 Q.nmapply = // XXX As proposed by "Redsandro"
 1858 Q.npost = function (object, name, args) {
 1859     return Q(object).npost(name, args);
 1860 };
 1861 
 1862 Promise.prototype.nmapply = // XXX As proposed by "Redsandro"
 1863 Promise.prototype.npost = function (name, args) {
 1864     var nodeArgs = array_slice(args || []);
 1865     var deferred = defer();
 1866     nodeArgs.push(deferred.makeNodeResolver());
 1867     this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
 1868     return deferred.promise;
 1869 };
 1870 
 1871 /**
 1872  * Calls a method of a Node-style object that accepts a Node-style
 1873  * callback, forwarding the given variadic arguments, plus a provided
 1874  * callback argument.
 1875  * @param object an object that has the named method
 1876  * @param {String} name name of the method of object
 1877  * @param ...args arguments to pass to the method; the callback will
 1878  * be provided by Q and appended to these arguments.
 1879  * @returns a promise for the value or error
 1880  */
 1881 Q.nsend = // XXX Based on Mark Miller's proposed "send"
 1882 Q.nmcall = // XXX Based on "Redsandro's" proposal
 1883 Q.ninvoke = function (object, name /*...args*/) {
 1884     var nodeArgs = array_slice(arguments, 2);
 1885     var deferred = defer();
 1886     nodeArgs.push(deferred.makeNodeResolver());
 1887     Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);
 1888     return deferred.promise;
 1889 };
 1890 
 1891 Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"
 1892 Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal
 1893 Promise.prototype.ninvoke = function (name /*...args*/) {
 1894     var nodeArgs = array_slice(arguments, 1);
 1895     var deferred = defer();
 1896     nodeArgs.push(deferred.makeNodeResolver());
 1897     this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
 1898     return deferred.promise;
 1899 };
 1900 
 1901 /**
 1902  * If a function would like to support both Node continuation-passing-style and
 1903  * promise-returning-style, it can end its internal promise chain with
 1904  * `nodeify(nodeback)`, forwarding the optional nodeback argument.  If the user
 1905  * elects to use a nodeback, the result will be sent there.  If they do not
 1906  * pass a nodeback, they will receive the result promise.
 1907  * @param object a result (or a promise for a result)
 1908  * @param {Function} nodeback a Node.js-style callback
 1909  * @returns either the promise or nothing
 1910  */
 1911 Q.nodeify = nodeify;
 1912 function nodeify(object, nodeback) {
 1913     return Q(object).nodeify(nodeback);
 1914 }
 1915 
 1916 Promise.prototype.nodeify = function (nodeback) {
 1917     if (nodeback) {
 1918         this.then(function (value) {
 1919             nextTick(function () {
 1920                 nodeback(null, value);
 1921             });
 1922         }, function (error) {
 1923             nextTick(function () {
 1924                 nodeback(error);
 1925             });
 1926         });
 1927     } else {
 1928         return this;
 1929     }
 1930 };
 1931 
 1932 // All code before this point will be filtered from stack traces.
 1933 var qEndingLine = captureLine();
 1934 
 1935 return Q;
 1936 
 1937 });