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