diff --git a/src/map.js b/src/map.js index dd7244e6d..ba247bc29 100644 --- a/src/map.js +++ b/src/map.js @@ -23,14 +23,15 @@ function MappingPromiseArray(promises, fn, limit, _filter) { this._limit = limit; this._inFlight = 0; this._queue = []; - async.invoke(this._asyncInit, this, undefined); + this._asyncQueue = []; + this._init$(undefined, RESOLVE_ARRAY); + if (!this._isResolved() && this._asyncQueue.length > 0) { + async.invoke(this._drainAsyncQueue, this, this._asyncQueue); + } + this._asyncQueue = undefined; } util.inherits(MappingPromiseArray, PromiseArray); -MappingPromiseArray.prototype._asyncInit = function() { - this._init$(undefined, RESOLVE_ARRAY); -}; - // The following hack is required because the super constructor // might call promiseFulfilled before this.callback = fn is set // @@ -60,6 +61,11 @@ MappingPromiseArray.prototype._promiseFulfilled = function (value, index) { if (this._isResolved()) return true; } } else { + if (this._asyncQueue !== undefined) { + this._asyncQueue.push([value, index]); + return false; + } + if (limit >= 1 && this._inFlight >= limit) { values[index] = value; this._queue.push(index); @@ -144,6 +150,15 @@ MappingPromiseArray.prototype._filter = function (booleans, values) { this._resolve(ret); }; +MappingPromiseArray.prototype._drainAsyncQueue = function (queue) { + var len = queue.length; + var item; + for (var i = 0; i < len && !this._isResolved(); ++i) { + item = queue[i]; + this._promiseFulfilled(item[0], item[1]); + } +}; + MappingPromiseArray.prototype.preservedValues = function () { return this._preservedValues; };