-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
timers.ts
73 lines (58 loc) · 1.38 KB
/
timers.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
73
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { v4 as getGuid } from 'uuid';
type TimeoutType = {
timestamp: number;
uuid: string;
};
const timeoutStore: Map<string, () => void> = new Map();
const allTimeouts: Set<TimeoutType> = new Set();
setInterval(() => {
if (!allTimeouts.size) {
return;
}
const now = Date.now();
allTimeouts.forEach((timeout: TimeoutType) => {
const { timestamp, uuid } = timeout;
if (now >= timestamp) {
if (timeoutStore.has(uuid)) {
const callback = timeoutStore.get(uuid);
if (callback) {
callback();
}
timeoutStore.delete(uuid);
}
allTimeouts.delete(timeout);
}
});
}, 100);
export function onTimeout(
timestamp: number,
callback: () => void,
id?: string
): string {
if (id && timeoutStore.has(id)) {
throw new ReferenceError(`onTimeout: ${id} already exists`);
}
let uuid = id || getGuid();
while (timeoutStore.has(uuid)) {
uuid = getGuid();
}
timeoutStore.set(uuid, callback);
allTimeouts.add({
timestamp,
uuid,
});
return uuid;
}
export function removeTimeout(uuid: string): void {
if (!timeoutStore.has(uuid)) {
return;
}
timeoutStore.delete(uuid);
allTimeouts.forEach((timeout: TimeoutType) => {
if (uuid === timeout.uuid) {
allTimeouts.delete(timeout);
}
});
}