forked from exadel-inc/esl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
delayed-task.ts
50 lines (45 loc) · 1.43 KB
/
delayed-task.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
import type {AnyToVoidFnSignature} from '../misc/functions';
/**
* Task placeholder with a single place for executing deferred task.
* Only one task can be planed per DelayedTask instance.
* @see put DelayedTask.put behaviour description.
*/
export class DelayedTask {
protected _fn: AnyToVoidFnSignature | null = null;
protected _timeout: number | null = null;
/** Execute deferred task immediately */
protected run = () => {
this._timeout = null;
this._fn && this._fn();
};
/** @return {Function} of currently deferred (planned) task */
public get fn() {
return this._fn;
}
/**
* Cancel deferred task and planning passed {@param task}
* @param delay - time to delay task execution
* - pass negative or false to execute task immediately
* - pass 0 to plan task to the macrotask
* - pass positive number x to delay task on x ms.
* */
public put(task: AnyToVoidFnSignature, delay: number | boolean = false) {
const prev = this.cancel();
if (typeof task === 'function') {
if (typeof delay === 'number' && delay >= 0) {
this._fn = task;
this._timeout = window.setTimeout(this.run, delay);
} else {
task();
}
}
return prev;
}
/** Cancel deferred (planned) task */
public cancel() {
const prev = this._fn;
(typeof this._timeout === 'number') && clearTimeout(this._timeout);
this._fn = this._timeout = null;
return prev;
}
}