| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 | "use strict";module.exports = function(Promise,                          PromiseArray,                          apiRejection,                          tryConvertToPromise,                          INTERNAL,                          debug) {var util = require("./util");var tryCatch = util.tryCatch;function ReductionPromiseArray(promises, fn, initialValue, _each) {    this.constructor$(promises);    var context = Promise._getContext();    this._fn = util.contextBind(context, fn);    if (initialValue !== undefined) {        initialValue = Promise.resolve(initialValue);        initialValue._attachCancellationCallback(this);    }    this._initialValue = initialValue;    this._currentCancellable = null;    if(_each === INTERNAL) {        this._eachValues = Array(this._length);    } else if (_each === 0) {        this._eachValues = null;    } else {        this._eachValues = undefined;    }    this._promise._captureStackTrace();    this._init$(undefined, -5);}util.inherits(ReductionPromiseArray, PromiseArray);ReductionPromiseArray.prototype._gotAccum = function(accum) {    if (this._eachValues !== undefined &&        this._eachValues !== null &&        accum !== INTERNAL) {        this._eachValues.push(accum);    }};ReductionPromiseArray.prototype._eachComplete = function(value) {    if (this._eachValues !== null) {        this._eachValues.push(value);    }    return this._eachValues;};ReductionPromiseArray.prototype._init = function() {};ReductionPromiseArray.prototype._resolveEmptyArray = function() {    this._resolve(this._eachValues !== undefined ? this._eachValues                                                 : this._initialValue);};ReductionPromiseArray.prototype.shouldCopyValues = function () {    return false;};ReductionPromiseArray.prototype._resolve = function(value) {    this._promise._resolveCallback(value);    this._values = null;};ReductionPromiseArray.prototype._resultCancelled = function(sender) {    if (sender === this._initialValue) return this._cancel();    if (this._isResolved()) return;    this._resultCancelled$();    if (this._currentCancellable instanceof Promise) {        this._currentCancellable.cancel();    }    if (this._initialValue instanceof Promise) {        this._initialValue.cancel();    }};ReductionPromiseArray.prototype._iterate = function (values) {    this._values = values;    var value;    var i;    var length = values.length;    if (this._initialValue !== undefined) {        value = this._initialValue;        i = 0;    } else {        value = Promise.resolve(values[0]);        i = 1;    }    this._currentCancellable = value;    for (var j = i; j < length; ++j) {        var maybePromise = values[j];        if (maybePromise instanceof Promise) {            maybePromise.suppressUnhandledRejections();        }    }    if (!value.isRejected()) {        for (; i < length; ++i) {            var ctx = {                accum: null,                value: values[i],                index: i,                length: length,                array: this            };            value = value._then(gotAccum, undefined, undefined, ctx, undefined);            if ((i & 127) === 0) {                value._setNoAsyncGuarantee();            }        }    }    if (this._eachValues !== undefined) {        value = value            ._then(this._eachComplete, undefined, undefined, this, undefined);    }    value._then(completed, completed, undefined, value, this);};Promise.prototype.reduce = function (fn, initialValue) {    return reduce(this, fn, initialValue, null);};Promise.reduce = function (promises, fn, initialValue, _each) {    return reduce(promises, fn, initialValue, _each);};function completed(valueOrReason, array) {    if (this.isFulfilled()) {        array._resolve(valueOrReason);    } else {        array._reject(valueOrReason);    }}function reduce(promises, fn, initialValue, _each) {    if (typeof fn !== "function") {        return apiRejection("expecting a function but got " + util.classString(fn));    }    var array = new ReductionPromiseArray(promises, fn, initialValue, _each);    return array.promise();}function gotAccum(accum) {    this.accum = accum;    this.array._gotAccum(accum);    var value = tryConvertToPromise(this.value, this.array._promise);    if (value instanceof Promise) {        this.array._currentCancellable = value;        return value._then(gotValue, undefined, undefined, this, undefined);    } else {        return gotValue.call(this, value);    }}function gotValue(value) {    var array = this.array;    var promise = array._promise;    var fn = tryCatch(array._fn);    promise._pushContext();    var ret;    if (array._eachValues !== undefined) {        ret = fn.call(promise._boundValue(), value, this.index, this.length);    } else {        ret = fn.call(promise._boundValue(),                              this.accum, value, this.index, this.length);    }    if (ret instanceof Promise) {        array._currentCancellable = ret;    }    var promiseCreated = promise._popContext();    debug.checkForgottenReturns(        ret,        promiseCreated,        array._eachValues !== undefined ? "Promise.each" : "Promise.reduce",        promise    );    return ret;}};
 |