Skip to content

Commit 3a40868

Browse files
committed
feat: async map
1 parent 1e98136 commit 3a40868

File tree

10 files changed

+100
-79
lines changed

10 files changed

+100
-79
lines changed

src/async/allSettled.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
interface SettleResult<T = any> {
3+
status: 'fulfilled' | 'rejected'
4+
value?: T
5+
reason?: any
6+
}
7+
8+
/**
9+
* Promise.allSettled() implementation
10+
*
11+
* @since 5.18.0
12+
* @category Async
13+
* @param collection
14+
* @returns
15+
*/
16+
export async function allSettled<T = any>(collection: Array<Promise<T>>): Promise<Array<SettleResult<T>>> {
17+
// @ts-ignore
18+
return Promise.all(
19+
collection
20+
.map(
21+
(item) => item
22+
.then((value) => ({ status: 'fulfilled', value }))
23+
.catch((reason) => ({ status: 'rejected', reason }))
24+
)
25+
);
26+
}

src/async/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
import { any } from '../any';
2+
import { allSettled } from './allSettled';
13
import { filter } from './filter';
4+
import { map } from './map';
5+
26

37
/**
48
* AsyncUtils
9+
*
510
* @since 5.18.0
611
*/
712
export const AsyncUtils = {
8-
filter
13+
filter, map, allSettled, any
914
};
1015

1116
export default AsyncUtils;

src/async/map.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { map as syncMap } from '../map';
2+
import type { ArrayIteratee, RecordIteratee, Tuple } from '../types';
3+
import { allSettled } from './allSettled';
4+
5+
6+
/**
7+
*
8+
* AsyncUtils.map, mapping values with async iteratee functions
9+
*
10+
* @since 5.18.0
11+
* @category Async
12+
* @param collection
13+
*/
14+
export async function map<T extends any[] | []>(collection: T): Promise<Tuple<T>>;
15+
export async function map<T, R = any>(collection: ArrayLike<T>, iteratee?: ArrayIteratee<T, Promise<R>>): Promise<Array<R>>;
16+
export async function map<T, R = any>(collection: Record<string, T>, iteratee?: RecordIteratee<T, Promise<R>>): Promise<Array<R>>;
17+
export async function map(collection: any, iteratee?: any): Promise<Array<any>>;
18+
export async function map(collection: any, iteratee?: any) {
19+
if (iteratee === undefined) {
20+
return syncMap(collection);
21+
}
22+
const results = await allSettled(syncMap(collection, iteratee));
23+
return syncMap(results, (result) => result.value ?? undefined);
24+
}
25+
26+
27+
export default map;

test/AsyncUtils.test.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,18 @@ describe('AsyncUtils Test Suite', () => {
1111
return (value % 2) === 0;
1212
});
1313

14-
1514
assert.deepStrictEqual(values, [2, 4]);
1615

1716
});
1817

18+
it('should support async allSettled function', async () => {
19+
const values = await AsyncUtils.allSettled([Promise.resolve(1), Promise.reject(2)]);
20+
assert.deepStrictEqual(values, [{ status: 'fulfilled', value: 1 }, { status: 'rejected', reason: 2 }]);
21+
});
22+
23+
it('should support async map function', async () => {
24+
const values = await AsyncUtils.map([1, 2, 3], async (value) => value * value);
25+
assert.deepStrictEqual(values, [1, 4, 9]);
26+
});
27+
1928
});

test/tsconfig.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"extends": "../tsconfig.base",
33
"compilerOptions": {
44
"checkJs": false,
5-
"noStrictGenericChecks": true
5+
"noStrictGenericChecks": true,
6+
"declaration": false
67
}
7-
}
8+
}

tsconfig.base.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,23 @@
55
"allowJs": true,
66
"esModuleInterop": true,
77
"moduleResolution": "node",
8+
"module": "CommonJS",
89
"declaration": true,
910
"lib": [
1011
"ES2015",
1112
"ES2017",
13+
"ES2020",
14+
"ES2020.Promise",
1215
"DOM"
1316
]
14-
}
17+
},
18+
"include": [
19+
"src"
20+
],
21+
"exclude": [
22+
"test",
23+
"lib",
24+
"dist",
25+
"deno"
26+
]
1527
}

tsconfig.es5.json

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,10 @@
11
{
2+
"extends": "./tsconfig.base",
23
"compilerOptions": {
3-
"charset": "UTF-8",
4-
"newLine": "lf",
5-
"allowJs": true,
64
"target": "ES5",
75
"module": "CommonJS",
86
"outDir": "dist/es5",
9-
"esModuleInterop": true,
10-
"moduleResolution": "node",
11-
"downlevelIteration": true,
127
"declaration": true,
13-
"lib": [
14-
"ES6",
15-
"ES2015.Symbol",
16-
"ES2017",
17-
"DOM"
18-
]
19-
},
20-
"include": [
21-
"src"
22-
],
23-
"exclude": [
24-
"src/test",
25-
"lib",
26-
"dist"
27-
]
8+
"downlevelIteration": true,
9+
}
2810
}

tsconfig.es6.json

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,9 @@
11
{
2+
"extends": "./tsconfig.base",
23
"compilerOptions": {
3-
"charset": "UTF-8",
4-
"newLine": "lf",
5-
"allowJs": true,
6-
"target": "ES6",
7-
"module": "ES6",
4+
"target": "ES2015",
5+
"module": "CommonJS",
86
"outDir": "dist/es6",
9-
"esModuleInterop": false,
10-
"moduleResolution": "node",
117
"declaration": true,
12-
"lib": [
13-
"ES6",
14-
"ES2015.Symbol",
15-
"ES2017",
16-
"DOM"
17-
]
18-
},
19-
"include": [
20-
"src"
21-
],
22-
"exclude": [
23-
"src/test",
24-
"lib",
25-
"dist"
26-
]
27-
}
8+
}
9+
}

tsconfig.json

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,6 @@
33
"compilerOptions": {
44
"target": "ES2018",
55
"module": "CommonJS",
6-
"outDir": "dist/node"
7-
},
8-
"include": [
9-
"src"
10-
],
11-
"exclude": [
12-
"test",
13-
"lib",
14-
"dist",
15-
"deno"
16-
]
6+
"outDir": "dist/node",
7+
}
178
}

tsconfig.umd.json

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,8 @@
11
{
2+
"extends": "./tsconfig.base",
23
"compilerOptions": {
3-
"charset": "UTF-8",
4-
"newLine": "lf",
5-
"allowJs": true,
6-
"target": "ES6",
7-
"esModuleInterop": true,
8-
"moduleResolution": "node",
9-
"lib": [
10-
"ES6",
11-
"ES2015.Symbol",
12-
"ES2017",
13-
"DOM"
14-
]
15-
},
16-
"include": [
17-
"src"
18-
],
19-
"exclude": [
20-
"src/test"
21-
]
4+
"target": "ES2015",
5+
"outDir": "dist/umd",
6+
"declaration": false,
7+
}
228
}

0 commit comments

Comments
 (0)