You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
7.9 KiB
165 lines
7.9 KiB
"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; |
|
}; |
|
|
|
};
|
|
|