2 module.exports = function(Promise,
8 var getDomain = Promise._getDomain;
9 var util = require("./util");
10 var tryCatch = util.tryCatch;
11 var errorObj = util.errorObj;
14 function MappingPromiseArray(promises, fn, limit, _filter) {
15 this.constructor$(promises);
16 this._promise._captureStackTrace();
17 var domain = getDomain();
18 this._callback = domain === null ? fn : domain.bind(fn);
19 this._preservedValues = _filter === INTERNAL
20 ? new Array(this.length())
24 this._queue = limit >= 1 ? [] : EMPTY_ARRAY;
25 this._init$(undefined, -2);
27 util.inherits(MappingPromiseArray, PromiseArray);
29 MappingPromiseArray.prototype._init = function () {};
31 MappingPromiseArray.prototype._promiseFulfilled = function (value, index) {
32 var values = this._values;
33 var length = this.length();
34 var preservedValues = this._preservedValues;
35 var limit = this._limit;
38 index = (index * -1) - 1;
39 values[index] = value;
43 if (this._isResolved()) return true;
46 if (limit >= 1 && this._inFlight >= limit) {
47 values[index] = value;
48 this._queue.push(index);
51 if (preservedValues !== null) preservedValues[index] = value;
53 var promise = this._promise;
54 var callback = this._callback;
55 var receiver = promise._boundValue();
56 promise._pushContext();
57 var ret = tryCatch(callback).call(receiver, value, index, length);
58 var promiseCreated = promise._popContext();
59 debug.checkForgottenReturns(
62 preservedValues !== null ? "Promise.filter" : "Promise.map",
65 if (ret === errorObj) {
70 var maybePromise = tryConvertToPromise(ret, this._promise);
71 if (maybePromise instanceof Promise) {
72 maybePromise = maybePromise._target();
73 var bitField = maybePromise._bitField;
75 if (((bitField & 50397184) === 0)) {
76 if (limit >= 1) this._inFlight++;
77 values[index] = maybePromise;
78 maybePromise._proxy(this, (index + 1) * -1);
80 } else if (((bitField & 33554432) !== 0)) {
81 ret = maybePromise._value();
82 } else if (((bitField & 16777216) !== 0)) {
83 this._reject(maybePromise._reason());
92 var totalResolved = ++this._totalResolved;
93 if (totalResolved >= length) {
94 if (preservedValues !== null) {
95 this._filter(values, preservedValues);
97 this._resolve(values);
104 MappingPromiseArray.prototype._drainQueue = function () {
105 var queue = this._queue;
106 var limit = this._limit;
107 var values = this._values;
108 while (queue.length > 0 && this._inFlight < limit) {
109 if (this._isResolved()) return;
110 var index = queue.pop();
111 this._promiseFulfilled(values[index], index);
115 MappingPromiseArray.prototype._filter = function (booleans, values) {
116 var len = values.length;
117 var ret = new Array(len);
119 for (var i = 0; i < len; ++i) {
120 if (booleans[i]) ret[j++] = values[i];
126 MappingPromiseArray.prototype.preservedValues = function () {
127 return this._preservedValues;
130 function map(promises, fn, options, _filter) {
131 if (typeof fn !== "function") {
132 return apiRejection("expecting a function but got " + util.classString(fn));
134 var limit = typeof options === "object" && options !== null
135 ? options.concurrency
137 limit = typeof limit === "number" &&
138 isFinite(limit) && limit >= 1 ? limit : 0;
139 return new MappingPromiseArray(promises, fn, limit, _filter).promise();
142 Promise.prototype.map = function (fn, options) {
143 return map(this, fn, options, null);
146 Promise.map = function (promises, fn, options, _filter) {
147 return map(promises, fn, options, _filter);