1"use strict"; 2module.exports = 3function(Promise, PromiseArray, tryConvertToPromise, INTERNAL, async, 4 getDomain) { 5var util = require("./util"); 6var canEvaluate = util.canEvaluate; 7var tryCatch = util.tryCatch; 8var errorObj = util.errorObj; 9var reject; 10 11if (!false) { 12if (canEvaluate) { 13 var thenCallback = function(i) { 14 return new Function("value", "holder", " \n\ 15 'use strict'; \n\ 16 holder.pIndex = value; \n\ 17 holder.checkFulfillment(this); \n\ 18 ".replace(/Index/g, i)); 19 }; 20 21 var promiseSetter = function(i) { 22 return new Function("promise", "holder", " \n\ 23 'use strict'; \n\ 24 holder.pIndex = promise; \n\ 25 ".replace(/Index/g, i)); 26 }; 27 28 var generateHolderClass = function(total) { 29 var props = new Array(total); 30 for (var i = 0; i < props.length; ++i) { 31 props[i] = "this.p" + (i+1); 32 } 33 var assignment = props.join(" = ") + " = null;"; 34 var cancellationCode= "var promise;\n" + props.map(function(prop) { 35 return " \n\ 36 promise = " + prop + "; \n\ 37 if (promise instanceof Promise) { \n\ 38 promise.cancel(); \n\ 39 } \n\ 40 "; 41 }).join("\n"); 42 var passedArguments = props.join(", "); 43 var name = "Holder$" + total; 44 45 46 var code = "return function(tryCatch, errorObj, Promise, async) { \n\ 47 'use strict'; \n\ 48 function [TheName](fn) { \n\ 49 [TheProperties] \n\ 50 this.fn = fn; \n\ 51 this.asyncNeeded = true; \n\ 52 this.now = 0; \n\ 53 } \n\ 54 \n\ 55 [TheName].prototype._callFunction = function(promise) { \n\ 56 promise._pushContext(); \n\ 57 var ret = tryCatch(this.fn)([ThePassedArguments]); \n\ 58 promise._popContext(); \n\ 59 if (ret === errorObj) { \n\ 60 promise._rejectCallback(ret.e, false); \n\ 61 } else { \n\ 62 promise._resolveCallback(ret); \n\ 63 } \n\ 64 }; \n\ 65 \n\ 66 [TheName].prototype.checkFulfillment = function(promise) { \n\ 67 var now = ++this.now; \n\ 68 if (now === [TheTotal]) { \n\ 69 if (this.asyncNeeded) { \n\ 70 async.invoke(this._callFunction, this, promise); \n\ 71 } else { \n\ 72 this._callFunction(promise); \n\ 73 } \n\ 74 \n\ 75 } \n\ 76 }; \n\ 77 \n\ 78 [TheName].prototype._resultCancelled = function() { \n\ 79 [CancellationCode] \n\ 80 }; \n\ 81 \n\ 82 return [TheName]; \n\ 83 }(tryCatch, errorObj, Promise, async); \n\ 84 "; 85 86 code = code.replace(/\[TheName\]/g, name) 87 .replace(/\[TheTotal\]/g, total) 88 .replace(/\[ThePassedArguments\]/g, passedArguments) 89 .replace(/\[TheProperties\]/g, assignment) 90 .replace(/\[CancellationCode\]/g, cancellationCode); 91 92 return new Function("tryCatch", "errorObj", "Promise", "async", code) 93 (tryCatch, errorObj, Promise, async); 94 }; 95 96 var holderClasses = []; 97 var thenCallbacks = []; 98 var promiseSetters = []; 99 100 for (var i = 0; i < 8; ++i) { 101 holderClasses.push(generateHolderClass(i + 1)); 102 thenCallbacks.push(thenCallback(i + 1)); 103 promiseSetters.push(promiseSetter(i + 1)); 104 } 105 106 reject = function (reason) { 107 this._reject(reason); 108 }; 109}} 110 111Promise.join = function () { 112 var last = arguments.length - 1; 113 var fn; 114 if (last > 0 && typeof arguments[last] === "function") { 115 fn = arguments[last]; 116 if (!false) { 117 if (last <= 8 && canEvaluate) { 118 var ret = new Promise(INTERNAL); 119 ret._captureStackTrace(); 120 var HolderClass = holderClasses[last - 1]; 121 var holder = new HolderClass(fn); 122 var callbacks = thenCallbacks; 123 124 for (var i = 0; i < last; ++i) { 125 var maybePromise = tryConvertToPromise(arguments[i], ret); 126 if (maybePromise instanceof Promise) { 127 maybePromise = maybePromise._target(); 128 var bitField = maybePromise._bitField; 129 ; 130 if (((bitField & 50397184) === 0)) { 131 maybePromise._then(callbacks[i], reject, 132 undefined, ret, holder); 133 promiseSetters[i](maybePromise, holder); 134 holder.asyncNeeded = false; 135 } else if (((bitField & 33554432) !== 0)) { 136 callbacks[i].call(ret, 137 maybePromise._value(), holder); 138 } else if (((bitField & 16777216) !== 0)) { 139 ret._reject(maybePromise._reason()); 140 } else { 141 ret._cancel(); 142 } 143 } else { 144 callbacks[i].call(ret, maybePromise, holder); 145 } 146 } 147 148 if (!ret._isFateSealed()) { 149 if (holder.asyncNeeded) { 150 var domain = getDomain(); 151 if (domain !== null) { 152 holder.fn = util.domainBind(domain, holder.fn); 153 } 154 } 155 ret._setAsyncGuaranteed(); 156 ret._setOnCancel(holder); 157 } 158 return ret; 159 } 160 } 161 } 162 var $_len = arguments.length;var args = new Array($_len); for(var $_i = 0; $_i < $_len; ++$_i) {args[$_i] = arguments[$_i];}; 163 if (fn) args.pop(); 164 var ret = new PromiseArray(args).promise(); 165 return fn !== undefined ? ret.spread(fn) : ret; 166}; 167 168}; 169