From 3bb03d0f269f9ba05a4ac384d2543c61f62f6284 Mon Sep 17 00:00:00 2001 From: overlookmotel Date: Thu, 21 Dec 2017 00:09:55 +0000 Subject: [PATCH] Fix Promise.map unhandled rejections (#1487) --- src/map.js | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/map.js b/src/map.js index dd7244e6d..506842ab9 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,12 @@ MappingPromiseArray.prototype._promiseFulfilled = function (value, index) { if (this._isResolved()) return true; } } else { + if (this._asyncQueue !== undefined) { + values[index] = value; + this._asyncQueue.push(index); + return false; + } + if (limit >= 1 && this._inFlight >= limit) { values[index] = value; this._queue.push(index); @@ -144,6 +151,16 @@ MappingPromiseArray.prototype._filter = function (booleans, values) { this._resolve(ret); }; +MappingPromiseArray.prototype._drainAsyncQueue = function (queue) { + var values = this._values; + var len = queue.length; + var index; + for (var i = 0; i < len && !this._isResolved(); ++i) { + index = queue[i]; + this._promiseFulfilled(values[index], index); + } +}; + MappingPromiseArray.prototype.preservedValues = function () { return this._preservedValues; };