Spaces:
Paused
Paused
| ; | |
| module.exports = function(Promise, | |
| PromiseArray, | |
| apiRejection, | |
| tryConvertToPromise, | |
| INTERNAL, | |
| debug) { | |
| var util = require("./util"); | |
| var tryCatch = util.tryCatch; | |
| var errorObj = util.errorObj; | |
| var async = Promise._async; | |
| function MappingPromiseArray(promises, fn, limit, _filter) { | |
| this.constructor$(promises); | |
| this._promise._captureStackTrace(); | |
| var context = Promise._getContext(); | |
| this._callback = util.contextBind(context, fn); | |
| this._preservedValues = _filter === INTERNAL | |
| ? new Array(this.length()) | |
| : null; | |
| this._limit = limit; | |
| this._inFlight = 0; | |
| this._queue = []; | |
| async.invoke(this._asyncInit, this, undefined); | |
| if (util.isArray(promises)) { | |
| for (var i = 0; i < promises.length; ++i) { | |
| var maybePromise = promises[i]; | |
| if (maybePromise instanceof Promise) { | |
| maybePromise.suppressUnhandledRejections(); | |
| } | |
| } | |
| } | |
| } | |
| util.inherits(MappingPromiseArray, PromiseArray); | |
| MappingPromiseArray.prototype._asyncInit = function() { | |
| this._init$(undefined, -2); | |
| }; | |
| MappingPromiseArray.prototype._init = function () {}; | |
| MappingPromiseArray.prototype._promiseFulfilled = function (value, index) { | |
| var values = this._values; | |
| var length = this.length(); | |
| var preservedValues = this._preservedValues; | |
| var limit = this._limit; | |
| if (index < 0) { | |
| index = (index * -1) - 1; | |
| values[index] = value; | |
| if (limit >= 1) { | |
| this._inFlight--; | |
| this._drainQueue(); | |
| if (this._isResolved()) return true; | |
| } | |
| } else { | |
| if (limit >= 1 && this._inFlight >= limit) { | |
| values[index] = value; | |
| this._queue.push(index); | |
| return false; | |
| } | |
| if (preservedValues !== null) preservedValues[index] = value; | |
| var promise = this._promise; | |
| var callback = this._callback; | |
| var receiver = promise._boundValue(); | |
| promise._pushContext(); | |
| var ret = tryCatch(callback).call(receiver, value, index, length); | |
| var promiseCreated = promise._popContext(); | |
| debug.checkForgottenReturns( | |
| ret, | |
| promiseCreated, | |
| preservedValues !== null ? "Promise.filter" : "Promise.map", | |
| promise | |
| ); | |
| if (ret === errorObj) { | |
| this._reject(ret.e); | |
| return true; | |
| } | |
| var maybePromise = tryConvertToPromise(ret, this._promise); | |
| if (maybePromise instanceof Promise) { | |
| maybePromise = maybePromise._target(); | |
| var bitField = maybePromise._bitField; | |
| ; | |
| if (((bitField & 50397184) === 0)) { | |
| if (limit >= 1) this._inFlight++; | |
| values[index] = maybePromise; | |
| maybePromise._proxy(this, (index + 1) * -1); | |
| return false; | |
| } else if (((bitField & 33554432) !== 0)) { | |
| ret = maybePromise._value(); | |
| } else if (((bitField & 16777216) !== 0)) { | |
| this._reject(maybePromise._reason()); | |
| return true; | |
| } else { | |
| this._cancel(); | |
| return true; | |
| } | |
| } | |
| values[index] = ret; | |
| } | |
| var totalResolved = ++this._totalResolved; | |
| if (totalResolved >= length) { | |
| if (preservedValues !== null) { | |
| this._filter(values, preservedValues); | |
| } else { | |
| this._resolve(values); | |
| } | |
| return true; | |
| } | |
| return false; | |
| }; | |
| MappingPromiseArray.prototype._drainQueue = function () { | |
| var queue = this._queue; | |
| var limit = this._limit; | |
| var values = this._values; | |
| while (queue.length > 0 && this._inFlight < limit) { | |
| if (this._isResolved()) return; | |
| var index = queue.pop(); | |
| this._promiseFulfilled(values[index], index); | |
| } | |
| }; | |
| MappingPromiseArray.prototype._filter = function (booleans, values) { | |
| var len = values.length; | |
| var ret = new Array(len); | |
| var j = 0; | |
| for (var i = 0; i < len; ++i) { | |
| if (booleans[i]) ret[j++] = values[i]; | |
| } | |
| ret.length = j; | |
| this._resolve(ret); | |
| }; | |
| MappingPromiseArray.prototype.preservedValues = function () { | |
| return this._preservedValues; | |
| }; | |
| function map(promises, fn, options, _filter) { | |
| if (typeof fn !== "function") { | |
| return apiRejection("expecting a function but got " + util.classString(fn)); | |
| } | |
| var limit = 0; | |
| if (options !== undefined) { | |
| if (typeof options === "object" && options !== null) { | |
| if (typeof options.concurrency !== "number") { | |
| return Promise.reject( | |
| new TypeError("'concurrency' must be a number but it is " + | |
| util.classString(options.concurrency))); | |
| } | |
| limit = options.concurrency; | |
| } else { | |
| return Promise.reject(new TypeError( | |
| "options argument must be an object but it is " + | |
| util.classString(options))); | |
| } | |
| } | |
| limit = typeof limit === "number" && | |
| isFinite(limit) && limit >= 1 ? limit : 0; | |
| return new MappingPromiseArray(promises, fn, limit, _filter).promise(); | |
| } | |
| Promise.prototype.map = function (fn, options) { | |
| return map(this, fn, options, null); | |
| }; | |
| Promise.map = function (promises, fn, options, _filter) { | |
| return map(promises, fn, options, _filter); | |
| }; | |
| }; | |