3 function(Promise, PromiseArray, tryConvertToPromise, INTERNAL) {
4 var util = require("./util");
5 var canEvaluate = util.canEvaluate;
6 var tryCatch = util.tryCatch;
7 var errorObj = util.errorObj;
12 var thenCallback = function(i) {
13 return new Function("value", "holder", " \n\
15 holder.pIndex = value; \n\
16 holder.checkFulfillment(this); \n\
17 ".replace(/Index/g, i));
20 var promiseSetter = function(i) {
21 return new Function("promise", "holder", " \n\
23 holder.pIndex = promise; \n\
24 ".replace(/Index/g, i));
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);
32 var assignment = props.join(" = ") + " = null;";
33 var cancellationCode= "var promise;\n" + props.map(function(prop) {
35 promise = " + prop + "; \n\
36 if (promise instanceof Promise) { \n\
41 var passedArguments = props.join(", ");
42 var name = "Holder$" + total;
45 var code = "return function(tryCatch, errorObj, Promise) { \n\
47 function [TheName](fn) { \n\
52 [TheName].prototype.checkFulfillment = function(promise) { \n\
53 var now = ++this.now; \n\
54 if (now === [TheTotal]) { \n\
55 promise._pushContext(); \n\
56 var callback = this.fn; \n\
57 var ret = tryCatch(callback)([ThePassedArguments]); \n\
58 promise._popContext(); \n\
59 if (ret === errorObj) { \n\
60 promise._rejectCallback(ret.e, false); \n\
62 promise._resolveCallback(ret); \n\
67 [TheName].prototype._resultCancelled = function() { \n\
68 [CancellationCode] \n\
72 }(tryCatch, errorObj, Promise); \n\
75 code = code.replace(/\[TheName\]/g, name)
76 .replace(/\[TheTotal\]/g, total)
77 .replace(/\[ThePassedArguments\]/g, passedArguments)
78 .replace(/\[TheProperties\]/g, assignment)
79 .replace(/\[CancellationCode\]/g, cancellationCode);
81 return new Function("tryCatch", "errorObj", "Promise", code)
82 (tryCatch, errorObj, Promise);
85 var holderClasses = [];
86 var thenCallbacks = [];
87 var promiseSetters = [];
89 for (var i = 0; i < 8; ++i) {
90 holderClasses.push(generateHolderClass(i + 1));
91 thenCallbacks.push(thenCallback(i + 1));
92 promiseSetters.push(promiseSetter(i + 1));
95 reject = function (reason) {
100 Promise.join = function () {
101 var last = arguments.length - 1;
103 if (last > 0 && typeof arguments[last] === "function") {
104 fn = arguments[last];
106 if (last <= 8 && canEvaluate) {
107 var ret = new Promise(INTERNAL);
108 ret._captureStackTrace();
109 var HolderClass = holderClasses[last - 1];
110 var holder = new HolderClass(fn);
111 var callbacks = thenCallbacks;
113 for (var i = 0; i < last; ++i) {
114 var maybePromise = tryConvertToPromise(arguments[i], ret);
115 if (maybePromise instanceof Promise) {
116 maybePromise = maybePromise._target();
117 var bitField = maybePromise._bitField;
119 if (((bitField & 50397184) === 0)) {
120 maybePromise._then(callbacks[i], reject,
121 undefined, ret, holder);
122 promiseSetters[i](maybePromise, holder);
123 } else if (((bitField & 33554432) !== 0)) {
124 callbacks[i].call(ret,
125 maybePromise._value(), holder);
126 } else if (((bitField & 16777216) !== 0)) {
127 ret._reject(maybePromise._reason());
132 callbacks[i].call(ret, maybePromise, holder);
135 if (!ret._isFateSealed()) {
136 ret._setAsyncGuaranteed();
137 ret._setOnCancel(holder);
143 var $_len = arguments.length;var args = new Array($_len); for(var $_i = 0; $_i < $_len; ++$_i) {args[$_i] = arguments[$_i];};
145 var ret = new PromiseArray(args).promise();
146 return fn !== undefined ? ret.spread(fn) : ret;