Skip to content

Commit

Permalink
feat: use promise.all in asyncForEach if wanted
Browse files Browse the repository at this point in the history
There is a warning if you use `inSequence`, which is the default. In the future the promise.all method will be the default.
  • Loading branch information
Arcath committed Apr 14, 2021
1 parent 3654b58 commit 0d669be
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 7 deletions.
20 changes: 18 additions & 2 deletions src/functions/async-for-each.spec.ts
Original file line number Diff line number Diff line change
@@ -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[] = []
Expand All @@ -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])
})
Expand Down
36 changes: 32 additions & 4 deletions src/functions/async-for-each.ts
Original file line number Diff line number Diff line change
@@ -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 <T>(array: T[], itterator: (value: T, index: number, array: T[]) => Promise<void>): Promise<void> => {
for(let index =0; index < array.length; index++){
//eslint-disable-next-line
await itterator(array[index], index, array)
export const asyncForEach = async <T>(array: T[], itterator: (value: T, index: number, array: T[]) => Promise<void>, options?: DeepPartial<AsyncForEachOptions>): Promise<void> => {
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<void>[] = []

array.forEach((value, index, arr) => {
promises.push(itterator(value, index, arr))
})

await Promise.all(promises)
}
2 changes: 1 addition & 1 deletion src/functions/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export type DeepPartial<T> = {
export const defaults = <T extends {}>(supplied: DeepPartial<T> | 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
Expand Down

0 comments on commit 0d669be

Please sign in to comment.