Skip to content

Commit ef668bb

Browse files
authored
Added async functions for Array.every, Array.find, and Array.some (#50)
* Added async functions for Array.every, Array.find, and Array.some * Upgraded dependencies
1 parent f7f1e3e commit ef668bb

File tree

10 files changed

+293
-66
lines changed

10 files changed

+293
-66
lines changed

README.md

Lines changed: 132 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ A collection of useful utility functions with associated TypeScript types.
2626
- [IndividualEqualityType](#individualequalitytype)
2727
- [randomNumberBetweenRange](#randomnumberbetweenrange)
2828
- [Async helpers](#async-helpers)
29+
- [asyncEvery](#asyncevery)
30+
- [asyncFilter](#asyncfilter)
2931
- [asyncForEach](#asyncforeach)
32+
- [asyncSome](#asyncsome)
3033
- [delay](#delay)
3134
- [Date helpers](#date-helpers)
3235
- [convertTimeUnit](#converttimeunit)
@@ -379,6 +382,90 @@ const random = randomNumberBetweenRange(2, 10);
379382

380383
---
381384

385+
#### asyncEvery
386+
387+
Allows you to run Array.every() with an async predicate function and await the result.
388+
389+
Method arguments:
390+
391+
| Parameter | Type | Optional | Description |
392+
| --------- | -------- | -------- | ----------------------------------------- |
393+
| items | Array<T> | false | The items to iterate over |
394+
| predicate | Function | false | A predicate function to run for each item |
395+
396+
Callback arguments:
397+
398+
| Parameter | Type | Optional | Description |
399+
| --------- | -------- | -------- | ----------------------------------- |
400+
| item | T | true | The current item from the loop |
401+
| index | number | true | The index of the given in the array |
402+
| array | Array<T> | true | The array provided |
403+
404+
Return type:
405+
406+
```typescript
407+
Promise<boolean>;
408+
```
409+
410+
**Example**
411+
412+
```typescript
413+
import { asyncEvery } from '@qntm-code/utils';
414+
415+
async function doAThing(): Promise<void> {
416+
// Array of items to iterate over
417+
const items: Array<string> = ['a', 'b', 'c'];
418+
419+
const result = await asyncEvery(items, async item => await someAsynchronousOperation(item));
420+
421+
functionToRunWhenAllItemsAreProcessed(result);
422+
}
423+
```
424+
425+
---
426+
427+
#### asyncFilter
428+
429+
Allows you to run Array.filter() with an async predicate function and await the result.
430+
431+
Method arguments:
432+
433+
| Parameter | Type | Optional | Description |
434+
| --------- | -------- | -------- | ----------------------------------------- |
435+
| items | Array<T> | false | The items to iterate over |
436+
| predicate | Function | false | A predicate function to run for each item |
437+
438+
Callback arguments:
439+
440+
| Parameter | Type | Optional | Description |
441+
| --------- | -------- | -------- | ----------------------------------- |
442+
| item | T | true | The current item from the loop |
443+
| index | number | true | The index of the given in the array |
444+
| array | Array<T> | true | The array provided |
445+
446+
Return type:
447+
448+
```typescript
449+
Promise<T[]>;
450+
```
451+
452+
**Example**
453+
454+
```typescript
455+
import { asyncFilter } from '@qntm-code/utils';
456+
457+
async function doAThing(): Promise<void> {
458+
// Array of items to iterate over
459+
const items: Array<string> = ['a', 'b', 'c'];
460+
461+
const results = await asyncFilter(items, async item => await someAsynchronousOperation(item));
462+
463+
functionToRunWhenAllItemsAreProcessed(results);
464+
}
465+
```
466+
467+
---
468+
382469
#### asyncForEach
383470

384471
Allows you to iterate over an array asynchronously.
@@ -401,7 +488,7 @@ Callback arguments:
401488
Return type:
402489

403490
```typescript
404-
Promise<void>
491+
Promise<void>;
405492
```
406493

407494
**Example**
@@ -413,16 +500,56 @@ async function doAThing(): Promise<void> {
413500
// Array of items to iterate over
414501
const items: Array<string> = ['a', 'b', 'c'];
415502

416-
await asyncForEach(items, async item => {
417-
const result = await someAsynchronousOperation(item);
418-
});
503+
await asyncForEach(items, async item => await someAsynchronousOperation(item));
419504

420505
functionToRunWhenAllItemsAreProcessed();
421506
}
422507
```
423508

424509
---
425510

511+
#### asyncSome
512+
513+
Allows you to run Array.some() with an async predicate function and await the result.
514+
515+
Method arguments:
516+
517+
| Parameter | Type | Optional | Description |
518+
| --------- | -------- | -------- | ----------------------------------------- |
519+
| items | Array<T> | false | The items to iterate over |
520+
| predicate | Function | false | A predicate function to run for each item |
521+
522+
Callback arguments:
523+
524+
| Parameter | Type | Optional | Description |
525+
| --------- | -------- | -------- | ----------------------------------- |
526+
| item | T | true | The current item from the loop |
527+
| index | number | true | The index of the given in the array |
528+
| array | Array<T> | true | The array provided |
529+
530+
Return type:
531+
532+
```typescript
533+
Promise<boolean>;
534+
```
535+
536+
**Example**
537+
538+
```typescript
539+
import { asyncSome } from '@qntm-code/utils';
540+
541+
async function doAThing(): Promise<void> {
542+
// Array of items to iterate over
543+
const items: Array<string> = ['a', 'b', 'c'];
544+
545+
const result = await asyncSome(items, async item => await someAsynchronousOperation(item));
546+
547+
functionToRunWhenAllItemsAreProcessed(result);
548+
}
549+
```
550+
551+
---
552+
426553
#### delay
427554

428555
Delays an async function using await given an optionally provided duration.
@@ -436,7 +563,7 @@ Method arguments:
436563
Return type:
437564

438565
```typescript
439-
Promise<void>
566+
Promise<void>;
440567
```
441568

442569
**Example**

src/async/asyncEvery.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Allows you to run [Array#every](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) asynchronously
3+
*/
4+
export async function asyncEvery<T>(array: T[], predicate: (item: T, index: number, array: T[]) => Promise<boolean>): Promise<boolean> {
5+
for (let index = 0, arrayLength = array.length; index < arrayLength; index++) {
6+
if (!(await predicate(array[index], index, array))) {
7+
return false;
8+
}
9+
}
10+
11+
return true;
12+
}

src/async/asyncFilter.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* Allows you to filter an array asynchronously
3+
*/
4+
export async function asyncFilter<T>(array: T[], callback: (item: T, index: number, array: T[]) => Promise<boolean>): Promise<T[]> {
5+
const results = await Promise.all(array.map(callback));
6+
7+
return array.filter((_v, index) => results[index]);
8+
}

src/async/asyncForEach.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
/**
22
* Allows you to iterate over an array asynchronously
33
*/
4-
// eslint-disable-next-line @typescript-eslint/ban-types
5-
export async function asyncForEach<T>(array: T[], callback: (item: T, index: number, array: T[]) => Promise<{}>): Promise<any> {
4+
export async function asyncForEach<T>(array: T[], callback: (item: T, index: number, array: T[]) => Promise<unknown>): Promise<void> {
65
for (let index = 0, arrayLength = array.length; index < arrayLength; index++) {
76
await callback(array[index], index, array);
87
}

src/async/asyncSome.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Allows you to run [Array#some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) asynchronously
3+
*/
4+
export async function asyncSome<T>(array: T[], predicate: (item: T, index: number, array: T[]) => Promise<boolean>): Promise<boolean> {
5+
for (let index = 0, arrayLength = array.length; index < arrayLength; index++) {
6+
if (await predicate(array[index], index, array)) {
7+
return true;
8+
}
9+
}
10+
11+
return false;
12+
}

src/async/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1+
export { asyncEvery } from './asyncEvery';
2+
export { asyncFilter } from './asyncFilter';
13
export { asyncForEach } from './asyncForEach';
4+
export { asyncSome } from './asyncSome';
25
export { delay } from './delay';

tests/async/asyncEvery.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { asyncEvery } from '../../src';
2+
3+
describe(`asyncEvery`, () => {
4+
it(`should return true if all items in the array match the predicate`, async () => {
5+
const result = await asyncEvery([1, 2, 3, 4, 5], value => {
6+
return new Promise(resolve => setTimeout(() => resolve(value % 2 === 0), 10));
7+
});
8+
9+
expect(result).toBe(false);
10+
});
11+
12+
it(`should return false if not all items in the array match the predicate`, async () => {
13+
const result = await asyncEvery([2, 4, 6, 8, 10], value => {
14+
return new Promise(resolve => setTimeout(() => resolve(value % 2 === 0), 10));
15+
});
16+
17+
expect(result).toBe(true);
18+
});
19+
});

tests/async/asyncFilter.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { asyncFilter } from '../../src';
2+
3+
describe(`asyncFilter`, () => {
4+
it(`should filter the array`, async () => {
5+
const result = await asyncFilter([1, 2, 3, 4, 5], value => {
6+
return new Promise(resolve => setTimeout(() => resolve(value % 2 === 0), 10));
7+
});
8+
9+
expect(result).toEqual([2, 4]);
10+
});
11+
});

tests/async/asyncSome.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { asyncSome } from '../../src';
2+
3+
describe(`asyncSome`, () => {
4+
it(`should return true if the predicate returns true for any value in the array`, async () => {
5+
const result = await asyncSome([1, 2, 3, 4, 5], value => {
6+
return new Promise(resolve => setTimeout(() => resolve(value % 2 === 0), 10));
7+
});
8+
9+
expect(result).toBe(true);
10+
});
11+
12+
it(`should return false if the predicate returns false for all values in the array`, async () => {
13+
const result = await asyncSome([1, 3, 5], value => {
14+
return new Promise(resolve => setTimeout(() => resolve(value % 2 === 0), 10));
15+
});
16+
17+
expect(result).toBe(false);
18+
});
19+
});

0 commit comments

Comments
 (0)