| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 | "use strict";module.exports =function(Promise, PromiseArray, tryConvertToPromise, INTERNAL, async) {var util = require("./util");var canEvaluate = util.canEvaluate;var tryCatch = util.tryCatch;var errorObj = util.errorObj;var reject;if (!false) {if (canEvaluate) {    var thenCallback = function(i) {        return new Function("value", "holder", "                             \n\            'use strict';                                                    \n\            holder.pIndex = value;                                           \n\            holder.checkFulfillment(this);                                   \n\            ".replace(/Index/g, i));    };    var promiseSetter = function(i) {        return new Function("promise", "holder", "                           \n\            'use strict';                                                    \n\            holder.pIndex = promise;                                         \n\            ".replace(/Index/g, i));    };    var generateHolderClass = function(total) {        var props = new Array(total);        for (var i = 0; i < props.length; ++i) {            props[i] = "this.p" + (i+1);        }        var assignment = props.join(" = ") + " = null;";        var cancellationCode= "var promise;\n" + props.map(function(prop) {            return "                                                         \n\                promise = " + prop + ";                                      \n\                if (promise instanceof Promise) {                            \n\                    promise.cancel();                                        \n\                }                                                            \n\            ";        }).join("\n");        var passedArguments = props.join(", ");        var name = "Holder$" + total;        var code = "return function(tryCatch, errorObj, Promise, async) {    \n\            'use strict';                                                    \n\            function [TheName](fn) {                                         \n\                [TheProperties]                                              \n\                this.fn = fn;                                                \n\                this.asyncNeeded = true;                                     \n\                this.now = 0;                                                \n\            }                                                                \n\                                                                             \n\            [TheName].prototype._callFunction = function(promise) {          \n\                promise._pushContext();                                      \n\                var ret = tryCatch(this.fn)([ThePassedArguments]);           \n\                promise._popContext();                                       \n\                if (ret === errorObj) {                                      \n\                    promise._rejectCallback(ret.e, false);                   \n\                } else {                                                     \n\                    promise._resolveCallback(ret);                           \n\                }                                                            \n\            };                                                               \n\                                                                             \n\            [TheName].prototype.checkFulfillment = function(promise) {       \n\                var now = ++this.now;                                        \n\                if (now === [TheTotal]) {                                    \n\                    if (this.asyncNeeded) {                                  \n\                        async.invoke(this._callFunction, this, promise);     \n\                    } else {                                                 \n\                        this._callFunction(promise);                         \n\                    }                                                        \n\                                                                             \n\                }                                                            \n\            };                                                               \n\                                                                             \n\            [TheName].prototype._resultCancelled = function() {              \n\                [CancellationCode]                                           \n\            };                                                               \n\                                                                             \n\            return [TheName];                                                \n\        }(tryCatch, errorObj, Promise, async);                               \n\        ";        code = code.replace(/\[TheName\]/g, name)            .replace(/\[TheTotal\]/g, total)            .replace(/\[ThePassedArguments\]/g, passedArguments)            .replace(/\[TheProperties\]/g, assignment)            .replace(/\[CancellationCode\]/g, cancellationCode);        return new Function("tryCatch", "errorObj", "Promise", "async", code)                           (tryCatch, errorObj, Promise, async);    };    var holderClasses = [];    var thenCallbacks = [];    var promiseSetters = [];    for (var i = 0; i < 8; ++i) {        holderClasses.push(generateHolderClass(i + 1));        thenCallbacks.push(thenCallback(i + 1));        promiseSetters.push(promiseSetter(i + 1));    }    reject = function (reason) {        this._reject(reason);    };}}Promise.join = function () {    var last = arguments.length - 1;    var fn;    if (last > 0 && typeof arguments[last] === "function") {        fn = arguments[last];        if (!false) {            if (last <= 8 && canEvaluate) {                var ret = new Promise(INTERNAL);                ret._captureStackTrace();                var HolderClass = holderClasses[last - 1];                var holder = new HolderClass(fn);                var callbacks = thenCallbacks;                for (var i = 0; i < last; ++i) {                    var maybePromise = tryConvertToPromise(arguments[i], ret);                    if (maybePromise instanceof Promise) {                        maybePromise = maybePromise._target();                        var bitField = maybePromise._bitField;                        ;                        if (((bitField & 50397184) === 0)) {                            maybePromise._then(callbacks[i], reject,                                               undefined, ret, holder);                            promiseSetters[i](maybePromise, holder);                            holder.asyncNeeded = false;                        } else if (((bitField & 33554432) !== 0)) {                            callbacks[i].call(ret,                                              maybePromise._value(), holder);                        } else if (((bitField & 16777216) !== 0)) {                            ret._reject(maybePromise._reason());                        } else {                            ret._cancel();                        }                    } else {                        callbacks[i].call(ret, maybePromise, holder);                    }                }                if (!ret._isFateSealed()) {                    if (holder.asyncNeeded) {                        var context = Promise._getContext();                        holder.fn = util.contextBind(context, holder.fn);                    }                    ret._setAsyncGuaranteed();                    ret._setOnCancel(holder);                }                return ret;            }        }    }    var $_len = arguments.length;var args = new Array($_len); for(var $_i = 0; $_i < $_len ; ++$_i) {args[$_i] = arguments[$_i ];};    if (fn) args.pop();    var ret = new PromiseArray(args).promise();    return fn !== undefined ? ret.spread(fn) : ret;};};
 |