'use strict'; // https://github.com/tc39/proposal-iterator-helpers // https://github.com/tc39/proposal-array-from-async var global = require('../internals/global'); var call = require('../internals/function-call'); var aCallable = require('../internals/a-callable'); var anObject = require('../internals/an-object'); var getBuiltIn = require('../internals/get-built-in'); var getMethod = require('../internals/get-method'); var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; var TypeError = global.TypeError; var createMethod = function (TYPE) { var IS_TO_ARRAY = TYPE == 0; var IS_FOR_EACH = TYPE == 1; var IS_EVERY = TYPE == 2; var IS_SOME = TYPE == 3; return function (iterator, fn, target) { anObject(iterator); var Promise = getBuiltIn('Promise'); var next = aCallable(iterator.next); var index = 0; var MAPPING = fn !== undefined; if (MAPPING || !IS_TO_ARRAY) aCallable(fn); return new Promise(function (resolve, reject) { var closeIteration = function (method, argument) { try { var returnMethod = getMethod(iterator, 'return'); if (returnMethod) { return Promise.resolve(call(returnMethod, iterator)).then(function () { method(argument); }, function (error) { reject(error); }); } } catch (error2) { return reject(error2); } method(argument); }; var onError = function (error) { closeIteration(reject, error); }; var loop = function () { try { if (IS_TO_ARRAY && (index > MAX_SAFE_INTEGER) && MAPPING) { throw TypeError('The allowed number of iterations has been exceeded'); } Promise.resolve(anObject(call(next, iterator))).then(function (step) { try { if (anObject(step).done) { if (IS_TO_ARRAY) { target.length = index; resolve(target); } else resolve(IS_SOME ? false : IS_EVERY || undefined); } else { var value = step.value; if (MAPPING) { Promise.resolve(IS_TO_ARRAY ? fn(value, index) : fn(value)).then(function (result) { if (IS_FOR_EACH) { loop(); } else if (IS_EVERY) { result ? loop() : closeIteration(resolve, false); } else if (IS_TO_ARRAY) { target[index++] = result; loop(); } else { result ? closeIteration(resolve, IS_SOME || value) : loop(); } }, onError); } else { target[index++] = value; loop(); } } } catch (error) { onError(error); } }, onError); } catch (error2) { onError(error2); } }; loop(); }); }; }; module.exports = { toArray: createMethod(0), forEach: createMethod(1), every: createMethod(2), some: createMethod(3), find: createMethod(4) };