generated from wopjs/template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
abortable.ts
77 lines (72 loc) · 2.08 KB
/
abortable.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
74
75
76
77
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- used in type doc
import type { DisposableStore } from "./disposable-store";
import type {
DisposableDisposer,
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- used in type doc
Disposer,
} from "./interface";
/**
* A {@link DisposableDisposer} that can be safely self-disposed.
* If it is attached to a {@link DisposableStore}, it will be removed from the store automatically when self-disposed.
*/
interface AbortableDisposable {
(): any;
dispose: (this: void) => any;
abortable: (onDispose?: () => void) => void;
}
interface AbortableDisposableImpl extends AbortableDisposable {
/** onDisposer */
_o?: (() => any) | null;
}
/**
* Enhance a {@link Disposer} so that it can be safely self-disposed.
*
* If it is attached to a {@link DisposableStore}, it will be removed from the store automatically when self-disposed.
*
* @param disposer A {@link Disposer}.
* @returns An abortable {@link DisposableDisposer}.
*
* @example
* ```js
* let timeoutId;
* const disposer = abortable(() => clearTimeout(timeoutId));
* timeoutId = setTimeout(() => console.log("hello"), 1000);
*
* // Add to a store
* const disposable = new DisposableStore();
* disposable.add(disposer);
*
* // Self-dispose
* disposer(); // setTimeout is cleared and the disposer is removed from the store.
* ```
*/
export const abortable: (disposer: () => any) => DisposableDisposer = (
disposer: (() => any) | null
): DisposableDisposer => {
const abortable: AbortableDisposableImpl = (): void => {
abortable.abortable();
if (disposer) {
disposer();
disposer = null;
}
};
abortable.dispose = abortable;
abortable.abortable = abortable$abortable;
return abortable;
};
function abortable$abortable(
this: AbortableDisposableImpl,
onDispose?: () => void
): void {
if (this._o) {
try {
this._o();
} catch (e) {
console.error(e);
}
}
this._o = onDispose;
}
export const isAbortable = (
disposable: any
): disposable is AbortableDisposable => disposable && disposable.abortable;