-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
105 lines (96 loc) · 2.63 KB
/
index.js
File metadata and controls
105 lines (96 loc) · 2.63 KB
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
async function onItem(iterable, fn) {
for await (const item of iterable) {
fn(item);
}
}
function forEach(iterable, fn, {
concurrency = 1,
stopOnError = true
} = {}) {
return new Promise((resolve, reject) => {
const iterator = iterable[Symbol.asyncIterator]();
let running = 0;
let currentIndex = 0;
let isDone = false;
const errors = [];
const next = async () => {
if (isDone) return;
const nextItem = await iterator.next();
const index = currentIndex++;
if (nextItem.done) {
isDone = true;
if (running === 0) {
if (!stopOnError && errors.length > 0) {
reject(new AggregateError(errors, `${errors.length} errors`));
}
else {
resolve();
}
}
return;
}
running++;
(async () => {
try {
await fn(await nextItem.value, index);
running--;
next();
}
catch (error) {
if (stopOnError) {
isDone = true;
reject(error);
}
else {
errors.push(error);
running--;
next();
}
}
})();
};
for (let index = 0; index < concurrency; index++) {
next();
if (isDone) {
break;
}
}
});
}
async function map(iterable, fn, opts) {
const results = [];
await forEach(iterable, async (item, index) => {
results[index] = await fn(item);
}, opts);
return results;
}
async function toArray(iterable, {concurrency = 1} = {}) {
return map(iterable, i => i, {concurrency});
}
async function* chunk(iterable, {chunkSize = 1} = {}) {
const iterator = iterable[Symbol.asyncIterator]();
let items = [];
let values = [];
main: while (true) {
if (items.length >= chunkSize) {
for (const item of await Promise.all(items)) {
if (item.done) break main;
values.push(item.value);
}
items = [];
values = [];
yield values;
}
items.push(iterator.next());
}
if (values.length) {
yield values;
}
}
module.exports = {
onItem,
forEach,
map,
toArray,
chunk,
};