This repository has been archived by the owner on Feb 10, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
PromiseUtils.ts
63 lines (58 loc) · 2.26 KB
/
PromiseUtils.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
// Copyright (c) 2023. Heusala Group Oy <info@heusalagroup.fi>. All rights reserved.
import { map } from "./functions/map";
export class PromiseUtils {
public static async waitTimeout (time: number) : Promise<void> {
return await new Promise( (resolve, reject) => {
try {
setTimeout(
() => {
resolve();
},
time
);
} catch (err) {
reject(err);
}
});
}
/**
* This method calls the `callback` function on each item in the `list`.
*
* It will start the `concurrentSize` amount of concurrent asynchronous jobs.
*
* @param list List of items to process asynchronously.
* @param callback The callback to call with each item as the argument. It
* is expected to return asynchronous promise in normal
* case. If this callback or the promise from it resolves as
* `false`, the processing will be stopped as soon as
* possible.
* @param concurrentSize The amount of concurrent asynchronous actions.
*/
public static async processConcurrently<T> (
list: readonly T[],
callback: (item: T) => false | undefined | void | Promise<false | undefined | void>,
concurrentSize: number
) : Promise<false | undefined | void> {
const queue = map(list, (item: T) => item);
let shouldEnd : boolean = false;
while ( queue.length && !shouldEnd ) {
let promises : Promise<any>[] = [];
let i = 0;
for(; i<concurrentSize && queue.length && !shouldEnd; i+=1) {
const item = queue.shift();
if (item) {
const step = async () : Promise<void> => {
const response = await callback(item);
if (response === false) {
shouldEnd = true;
}
};
const promise = step();
promises.push(promise);
}
}
await Promise.allSettled(promises);
}
if (shouldEnd) return false;
}
}