| "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; |
| }; |
| |
| }; |