import { ForEachIterator, AsyncErrorCallback, Dictionary, NumericDictionary, PromiseResolver, PromiseRejector, ParallelCallback } from "../interfaces"; import { once } from "../common"; function seriesArray( data: T[], iterator: ForEachIterator, final?: AsyncErrorCallback ): void { let loop = function(i: number): void { if (i < data.length) { iterator(data[i], i, once(function(err?: E): void { if (err !== null && err !== undefined) { final && final(err); } else { loop(i + 1); } })); } else { final && final(); } }; loop(0); } function parallelArray( data: T[], iterator: ForEachIterator, final?: ParallelCallback ): void { if (final) { let errorNum: number = 0, completed: number = 0; let errors: NumericDictionary = {}; for (let i = 0; i < data.length; i++) { iterator(data[i], i, once(function(err?: E): void { completed++; if (err) { errors[i] = err; errorNum++; } if (completed === data.length) { final(errorNum ? errors : null); } })); } } else { for (let i = 0; i < data.length; i++) { iterator(data[i], i, function(err?: E): void {}); } } } function seriesDict( data: Dictionary, iterator: ForEachIterator, final: AsyncErrorCallback ): void { let keys: string[] = []; let dataObject: Dictionary = {}; for (let key in data) { keys.push(key); dataObject[key] = data[key]; } let loop = function(i: number): void { if (i < keys.length) { iterator(dataObject[keys[i]], keys[i], once(function(err?: E): void { if (err !== null && err !== undefined) { final(err); } else { loop(i + 1); } })); } else { final(); } }; loop(0); } function parallelDict( data: Dictionary, iterator: ForEachIterator, final: ParallelCallback ): void { let i: number = 0; let keys: string[] = []; let dataObject: Dictionary = {}; for (let key in data) { keys.push(key); dataObject[key] = data[key]; } if (final) { let errorNum: number = 0, completed: number = 0; let errors: NumericDictionary = {}; for (let i = 0; i < keys.length; i++) { iterator(dataObject[keys[i]], keys[i], once(function(err?: E): void { completed++; if (err) { errors[i] = err; errorNum++; } if (completed === keys.length) { final(errorNum ? errors : null); } })); } } else { for (let i = 0; i < keys.length; i++) { iterator(dataObject[keys[i]], keys[i], function(err?: E): void {}); } } } /** * This method enum all items in an array or an object one by one, * with index value. */ export function series( data: Dictionary | T[], next: ForEachIterator, final: AsyncErrorCallback ): void { if (data instanceof Array) { data = data.slice(); seriesArray(data, next, final); } else { seriesDict(data, next, final); } }; /** * This method enum all items in an array or an object at once, * with index value. */ export function parallel( data: Dictionary | T[], next: ForEachIterator, final: ParallelCallback ): void { if (data instanceof Array) { data = data.slice(); parallelArray(data, next, final); } else { parallelDict(data, next, final); } }; export function forEach_Promise( data: Dictionary | T[], next: ForEachIterator ): Promise { return new Promise(function( resolve: PromiseResolver, reject: PromiseRejector ): void { series(data, next, function(err?: E): void { err ? reject(err) : resolve(); }); }); }