From 0d669be0826df0d97bc65d820ef757624b9159b6 Mon Sep 17 00:00:00 2001 From: Adam Laycock Date: Wed, 14 Apr 2021 11:27:48 +0100 Subject: [PATCH] feat: use promise.all in asyncForEach if wanted There is a warning if you use `inSequence`, which is the default. In the future the promise.all method will be the default. --- src/functions/async-for-each.spec.ts | 20 ++++++++++++++-- src/functions/async-for-each.ts | 36 ++++++++++++++++++++++++---- src/functions/defaults.ts | 2 +- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/functions/async-for-each.spec.ts b/src/functions/async-for-each.spec.ts index c9f39a7..85e8e0f 100644 --- a/src/functions/async-for-each.spec.ts +++ b/src/functions/async-for-each.spec.ts @@ -1,6 +1,6 @@ import {asyncForEach} from '../' -describe('Async For Each', () => { +describe('Async For Each (in sequence)', () => { it('should work async', async () => { const array = [1,2,3] const newArray: number[] = [] @@ -12,7 +12,23 @@ describe('Async For Each', () => { resolve() }, 100) }) - }) + }, {inSequence: true}) + + expect(newArray).toStrictEqual([2,3,4]) + }) + + it('should work async (not in sequence)', async () => { + const array = [1,2,3] + const newArray: number[] = [] + + await asyncForEach(array, (n, i) => { + return new Promise((resolve) => { + setTimeout(() => { + newArray[i] = n + 1 + resolve() + }, 100) + }) + }, {inSequence: false}) expect(newArray).toStrictEqual([2,3,4]) }) diff --git a/src/functions/async-for-each.ts b/src/functions/async-for-each.ts index 0e43cee..3084f37 100644 --- a/src/functions/async-for-each.ts +++ b/src/functions/async-for-each.ts @@ -1,12 +1,40 @@ +import {defaults, DeepPartial} from './defaults' + +interface AsyncForEachOptions{ + /** Use the legacy style for look for itterations, when false this is a wrapper for `Promise.all` + * The default in 1.x will be to set this to `false`. For 0.x it is `true` + */ + inSequence: boolean +} + +const defaultOptions: AsyncForEachOptions = { + inSequence: true +} + /** * Runs the supplied itterator for all elements in the array asyncronously. * * @param array The array to itterate through. * @param itterator The async function to run for each element. */ -export const asyncForEach = async (array: T[], itterator: (value: T, index: number, array: T[]) => Promise): Promise => { - for(let index =0; index < array.length; index++){ - //eslint-disable-next-line - await itterator(array[index], index, array) +export const asyncForEach = async (array: T[], itterator: (value: T, index: number, array: T[]) => Promise, options?: DeepPartial): Promise => { + const {inSequence} = defaults(options, defaultOptions) + + if(inSequence){ + console.warn('in sequence is going to be removed in the future, for 0.x it is default on, soon it will change to default off.') + for(let index =0; index < array.length; index++){ + //eslint-disable-next-line + await itterator(array[index], index, array) + } + + return } + + const promises: Promise[] = [] + + array.forEach((value, index, arr) => { + promises.push(itterator(value, index, arr)) + }) + + await Promise.all(promises) } \ No newline at end of file diff --git a/src/functions/defaults.ts b/src/functions/defaults.ts index 3e795f2..1aee3f7 100644 --- a/src/functions/defaults.ts +++ b/src/functions/defaults.ts @@ -14,7 +14,7 @@ export type DeepPartial = { export const defaults = (supplied: DeepPartial | undefined, defaultValues: T) => { const result: T = {...defaultValues} - Object.keys(supplied || {}).forEach((key) => { + Object.keys(supplied ?? {}).forEach((key) => { if(typeof (defaultValues as {[key: string]: string})[key] === 'object'){ (result as {[key: string]: string})[key] = defaults( //eslint-disable-next-line