twitst4tz

twitter statistics web application
Log | Files | Refs | README | LICENSE

reduce.js (5372B)


      1 "use strict";
      2 module.exports = function(Promise,
      3                           PromiseArray,
      4                           apiRejection,
      5                           tryConvertToPromise,
      6                           INTERNAL,
      7                           debug) {
      8 var util = require("./util");
      9 var tryCatch = util.tryCatch;
     10 
     11 function ReductionPromiseArray(promises, fn, initialValue, _each) {
     12     this.constructor$(promises);
     13     var context = Promise._getContext();
     14     this._fn = util.contextBind(context, fn);
     15     if (initialValue !== undefined) {
     16         initialValue = Promise.resolve(initialValue);
     17         initialValue._attachCancellationCallback(this);
     18     }
     19     this._initialValue = initialValue;
     20     this._currentCancellable = null;
     21     if(_each === INTERNAL) {
     22         this._eachValues = Array(this._length);
     23     } else if (_each === 0) {
     24         this._eachValues = null;
     25     } else {
     26         this._eachValues = undefined;
     27     }
     28     this._promise._captureStackTrace();
     29     this._init$(undefined, -5);
     30 }
     31 util.inherits(ReductionPromiseArray, PromiseArray);
     32 
     33 ReductionPromiseArray.prototype._gotAccum = function(accum) {
     34     if (this._eachValues !== undefined &&
     35         this._eachValues !== null &&
     36         accum !== INTERNAL) {
     37         this._eachValues.push(accum);
     38     }
     39 };
     40 
     41 ReductionPromiseArray.prototype._eachComplete = function(value) {
     42     if (this._eachValues !== null) {
     43         this._eachValues.push(value);
     44     }
     45     return this._eachValues;
     46 };
     47 
     48 ReductionPromiseArray.prototype._init = function() {};
     49 
     50 ReductionPromiseArray.prototype._resolveEmptyArray = function() {
     51     this._resolve(this._eachValues !== undefined ? this._eachValues
     52                                                  : this._initialValue);
     53 };
     54 
     55 ReductionPromiseArray.prototype.shouldCopyValues = function () {
     56     return false;
     57 };
     58 
     59 ReductionPromiseArray.prototype._resolve = function(value) {
     60     this._promise._resolveCallback(value);
     61     this._values = null;
     62 };
     63 
     64 ReductionPromiseArray.prototype._resultCancelled = function(sender) {
     65     if (sender === this._initialValue) return this._cancel();
     66     if (this._isResolved()) return;
     67     this._resultCancelled$();
     68     if (this._currentCancellable instanceof Promise) {
     69         this._currentCancellable.cancel();
     70     }
     71     if (this._initialValue instanceof Promise) {
     72         this._initialValue.cancel();
     73     }
     74 };
     75 
     76 ReductionPromiseArray.prototype._iterate = function (values) {
     77     this._values = values;
     78     var value;
     79     var i;
     80     var length = values.length;
     81     if (this._initialValue !== undefined) {
     82         value = this._initialValue;
     83         i = 0;
     84     } else {
     85         value = Promise.resolve(values[0]);
     86         i = 1;
     87     }
     88 
     89     this._currentCancellable = value;
     90 
     91     for (var j = i; j < length; ++j) {
     92         var maybePromise = values[j];
     93         if (maybePromise instanceof Promise) {
     94             maybePromise.suppressUnhandledRejections();
     95         }
     96     }
     97 
     98     if (!value.isRejected()) {
     99         for (; i < length; ++i) {
    100             var ctx = {
    101                 accum: null,
    102                 value: values[i],
    103                 index: i,
    104                 length: length,
    105                 array: this
    106             };
    107 
    108             value = value._then(gotAccum, undefined, undefined, ctx, undefined);
    109 
    110             if ((i & 127) === 0) {
    111                 value._setNoAsyncGuarantee();
    112             }
    113         }
    114     }
    115 
    116     if (this._eachValues !== undefined) {
    117         value = value
    118             ._then(this._eachComplete, undefined, undefined, this, undefined);
    119     }
    120     value._then(completed, completed, undefined, value, this);
    121 };
    122 
    123 Promise.prototype.reduce = function (fn, initialValue) {
    124     return reduce(this, fn, initialValue, null);
    125 };
    126 
    127 Promise.reduce = function (promises, fn, initialValue, _each) {
    128     return reduce(promises, fn, initialValue, _each);
    129 };
    130 
    131 function completed(valueOrReason, array) {
    132     if (this.isFulfilled()) {
    133         array._resolve(valueOrReason);
    134     } else {
    135         array._reject(valueOrReason);
    136     }
    137 }
    138 
    139 function reduce(promises, fn, initialValue, _each) {
    140     if (typeof fn !== "function") {
    141         return apiRejection("expecting a function but got " + util.classString(fn));
    142     }
    143     var array = new ReductionPromiseArray(promises, fn, initialValue, _each);
    144     return array.promise();
    145 }
    146 
    147 function gotAccum(accum) {
    148     this.accum = accum;
    149     this.array._gotAccum(accum);
    150     var value = tryConvertToPromise(this.value, this.array._promise);
    151     if (value instanceof Promise) {
    152         this.array._currentCancellable = value;
    153         return value._then(gotValue, undefined, undefined, this, undefined);
    154     } else {
    155         return gotValue.call(this, value);
    156     }
    157 }
    158 
    159 function gotValue(value) {
    160     var array = this.array;
    161     var promise = array._promise;
    162     var fn = tryCatch(array._fn);
    163     promise._pushContext();
    164     var ret;
    165     if (array._eachValues !== undefined) {
    166         ret = fn.call(promise._boundValue(), value, this.index, this.length);
    167     } else {
    168         ret = fn.call(promise._boundValue(),
    169                               this.accum, value, this.index, this.length);
    170     }
    171     if (ret instanceof Promise) {
    172         array._currentCancellable = ret;
    173     }
    174     var promiseCreated = promise._popContext();
    175     debug.checkForgottenReturns(
    176         ret,
    177         promiseCreated,
    178         array._eachValues !== undefined ? "Promise.each" : "Promise.reduce",
    179         promise
    180     );
    181     return ret;
    182 }
    183 };