import {IterateFunction, Resolvable} from "./interfaces"; export class PromiseMap { public static map(iterable: Resolvable>>, mapper: IterateFunction, options: { concurrency: number } = {concurrency: Infinity}): Promise { let concurrency = options.concurrency || Infinity; let params = {index: 0}, results = [], iterator = iterable[Symbol.iterator](), promises = []; while (concurrency-- > 0) { let promise = PromiseMap._mapWrapper(mapper, iterator, results, params); if (!promise) { break; } promises.push(promise); } return Promise.all(promises).then(() => results); } private static _mapWrapper(mapper: IterateFunction, iterator: IterableIterator, results: any[], params: { index: number }) { let next = iterator.next(); if (next.done) { return null; } let i = params.index++, mapped = mapper(next.value, i); return Promise.resolve(mapped).then(resolved => { results[i] = resolved; return PromiseMap._mapWrapper(mapper, iterator, results, params) }) } }