-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpool.ts
37 lines (36 loc) · 961 Bytes
/
pool.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
import type { Result } from "./types.ts";
export function* pool<T, U, E = unknown>(
threshold: number,
args: Iterable<T>,
func: (value: T, id: number) => Promise<U>,
): Generator<Promise<Result<U, E>>, void, unknown> {
let running = 0;
const waitings = [] as ((value: number | PromiseLike<number>) => void)[];
const waitForReady = async () => {
running++;
if (running <= threshold) return running - 1;
return await new Promise<number>(
(resolve) => waitings.push(resolve),
);
};
for (const arg of args) {
yield (async () => {
const id = await waitForReady();
try {
return {
success: true,
value: await func(arg, id),
};
} catch (e: unknown) {
return {
success: false,
reason: e as E,
};
} finally {
running--;
waitings.shift()?.(id);
}
})();
}
// 実行しきれない可能性はある?
}