-
Notifications
You must be signed in to change notification settings - Fork 4
/
map-limit.ts
72 lines (64 loc) · 1.61 KB
/
map-limit.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/**
*
* @param input
* @param limit
* @param iteratee
*/
async function mapLimit<T, V>(
input: readonly T[],
limit: number,
iteratee: (value: T, index: number) => Promise<V>,
): Promise<V[]>;
async function mapLimit<T, V>(
input: readonly T[],
limit: number,
iteratee: (value: T) => Promise<V>,
): Promise<V[]>;
async function mapLimit<T extends Object, V>(
input: T,
limit: number,
iteratee: (value: T[keyof T], key: string) => Promise<V>,
): Promise<V[]>;
async function mapLimit<T extends Object, V>(
input: T,
limit: number,
iteratee: (value: T[keyof T]) => Promise<V>,
): Promise<V[]>;
async function mapLimit<V>(input: any, limit: number, iteratee: any): Promise<V[]> {
if (!input) {
return [];
}
const isArray = input.length !== undefined;
const size = (() => {
if (isArray) {
return input.length;
}
let count = 0;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const _ in input) {
++count;
}
return count;
})();
const allValues = new Array(size);
const results = new Array(size);
let i = 0;
for (const key in input) {
const possiblyNumericKey = isArray ? i : key;
allValues[size - 1 - i] = [input[key], i, possiblyNumericKey];
++i;
}
const execute = async () => {
while (allValues.length > 0) {
const [val, index, key] = allValues.pop();
results[index] = await iteratee(val, key);
}
};
const allExecutors: Promise<any>[] = [];
for (let j = 0; j < limit; ++j) {
allExecutors.push(execute());
}
await Promise.all(allExecutors);
return results;
}
export default mapLimit;