Version 1
[yaffs-website] / node_modules / bluebird / js / release / map.js
1 "use strict";
2 module.exports = function(Promise,
3                           PromiseArray,
4                           apiRejection,
5                           tryConvertToPromise,
6                           INTERNAL,
7                           debug) {
8 var getDomain = Promise._getDomain;
9 var util = require("./util");
10 var tryCatch = util.tryCatch;
11 var errorObj = util.errorObj;
12 var EMPTY_ARRAY = [];
13
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())
21         : null;
22     this._limit = limit;
23     this._inFlight = 0;
24     this._queue = limit >= 1 ? [] : EMPTY_ARRAY;
25     this._init$(undefined, -2);
26 }
27 util.inherits(MappingPromiseArray, PromiseArray);
28
29 MappingPromiseArray.prototype._init = function () {};
30
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;
36
37     if (index < 0) {
38         index = (index * -1) - 1;
39         values[index] = value;
40         if (limit >= 1) {
41             this._inFlight--;
42             this._drainQueue();
43             if (this._isResolved()) return true;
44         }
45     } else {
46         if (limit >= 1 && this._inFlight >= limit) {
47             values[index] = value;
48             this._queue.push(index);
49             return false;
50         }
51         if (preservedValues !== null) preservedValues[index] = value;
52
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(
60             ret,
61             promiseCreated,
62             preservedValues !== null ? "Promise.filter" : "Promise.map",
63             promise
64         );
65         if (ret === errorObj) {
66             this._reject(ret.e);
67             return true;
68         }
69
70         var maybePromise = tryConvertToPromise(ret, this._promise);
71         if (maybePromise instanceof Promise) {
72             maybePromise = maybePromise._target();
73             var bitField = maybePromise._bitField;
74             ;
75             if (((bitField & 50397184) === 0)) {
76                 if (limit >= 1) this._inFlight++;
77                 values[index] = maybePromise;
78                 maybePromise._proxy(this, (index + 1) * -1);
79                 return false;
80             } else if (((bitField & 33554432) !== 0)) {
81                 ret = maybePromise._value();
82             } else if (((bitField & 16777216) !== 0)) {
83                 this._reject(maybePromise._reason());
84                 return true;
85             } else {
86                 this._cancel();
87                 return true;
88             }
89         }
90         values[index] = ret;
91     }
92     var totalResolved = ++this._totalResolved;
93     if (totalResolved >= length) {
94         if (preservedValues !== null) {
95             this._filter(values, preservedValues);
96         } else {
97             this._resolve(values);
98         }
99         return true;
100     }
101     return false;
102 };
103
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);
112     }
113 };
114
115 MappingPromiseArray.prototype._filter = function (booleans, values) {
116     var len = values.length;
117     var ret = new Array(len);
118     var j = 0;
119     for (var i = 0; i < len; ++i) {
120         if (booleans[i]) ret[j++] = values[i];
121     }
122     ret.length = j;
123     this._resolve(ret);
124 };
125
126 MappingPromiseArray.prototype.preservedValues = function () {
127     return this._preservedValues;
128 };
129
130 function map(promises, fn, options, _filter) {
131     if (typeof fn !== "function") {
132         return apiRejection("expecting a function but got " + util.classString(fn));
133     }
134     var limit = typeof options === "object" && options !== null
135         ? options.concurrency
136         : 0;
137     limit = typeof limit === "number" &&
138         isFinite(limit) && limit >= 1 ? limit : 0;
139     return new MappingPromiseArray(promises, fn, limit, _filter).promise();
140 }
141
142 Promise.prototype.map = function (fn, options) {
143     return map(this, fn, options, null);
144 };
145
146 Promise.map = function (promises, fn, options, _filter) {
147     return map(promises, fn, options, _filter);
148 };
149
150
151 };