'use strict'; var $ = require('../internals/export'); var call = require('../internals/function-call'); var aCallable = require('../internals/a-callable'); var anObject = require('../internals/an-object'); var isObject = require('../internals/is-object'); var getBuiltIn = require('../internals/get-built-in'); var getIteratorDirect = require('../internals/get-iterator-direct'); var closeAsyncIteration = require('../internals/async-iterator-close'); var Promise = getBuiltIn('Promise'); var $TypeError = TypeError; // `AsyncIterator.prototype.reduce` method // https://github.com/tc39/proposal-async-iterator-helpers $({ target: 'AsyncIterator', proto: true, real: true }, { reduce: function reduce(reducer /* , initialValue */) { anObject(this); aCallable(reducer); var record = getIteratorDirect(this); var iterator = record.iterator; var next = record.next; var noInitial = arguments.length < 2; var accumulator = noInitial ? undefined : arguments[1]; var counter = 0; return new Promise(function (resolve, reject) { var ifAbruptCloseAsyncIterator = function (error) { closeAsyncIteration(iterator, reject, error, reject); }; var loop = function () { try { Promise.resolve(anObject(call(next, iterator))).then(function (step) { try { if (anObject(step).done) { noInitial ? reject($TypeError('Reduce of empty iterator with no initial value')) : resolve(accumulator); } else { var value = step.value; if (noInitial) { noInitial = false; accumulator = value; loop(); } else try { var result = reducer(accumulator, value, counter); var handler = function ($result) { accumulator = $result; loop(); }; if (isObject(result)) Promise.resolve(result).then(handler, ifAbruptCloseAsyncIterator); else handler(result); } catch (error3) { ifAbruptCloseAsyncIterator(error3); } } counter++; } catch (error2) { reject(error2); } }, reject); } catch (error) { reject(error); } }; loop(); }); } });