🥂 Initial commit
This commit is contained in:
67
tools/utils/task-debouncer.js
Normal file
67
tools/utils/task-debouncer.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* #### TaskDebouncer
|
||||
*
|
||||
* Executes a task after a certain delay, but cancels the execution if
|
||||
* a new task is sent before the delay expires. Also, if a task is
|
||||
* already being executed, the new task is queued and executed after
|
||||
* the current one finishes. It will only execute the task that was
|
||||
* sent last.
|
||||
*/
|
||||
export class TaskDebouncer {
|
||||
constructor(debounceDelay) {
|
||||
this.debounceDelay = debounceDelay;
|
||||
this.queued = undefined;
|
||||
this.isProcessing = false;
|
||||
this.timerId = null;
|
||||
}
|
||||
|
||||
#clearQueue() {
|
||||
this.queued = undefined;
|
||||
}
|
||||
|
||||
#enqueue(executor, args) {
|
||||
this.queued = { executor, args };
|
||||
this.#processQueue();
|
||||
}
|
||||
|
||||
#setProcessing(value) {
|
||||
this.isProcessing = value;
|
||||
}
|
||||
|
||||
async #processQueue() {
|
||||
if (this.isProcessing || !this.queued) {
|
||||
return;
|
||||
}
|
||||
const { executor, args } = this.queued;
|
||||
this.#clearQueue();
|
||||
|
||||
// execute the task
|
||||
this.#setProcessing(true);
|
||||
await executor(...args);
|
||||
this.#setProcessing(false);
|
||||
|
||||
// continue with the next task
|
||||
this.#continue();
|
||||
}
|
||||
|
||||
#continue() {
|
||||
if (this.queued) {
|
||||
this.#processQueue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a task to the queue. If a task is already being executed,
|
||||
* the new task is queued and executed after the current one finishes.
|
||||
* It will only execute the task if no other task is sent before the
|
||||
* delay expires or before the current task finishes.
|
||||
*
|
||||
* IOW, it will only execute the task that was sent last.
|
||||
*/
|
||||
add(executor, ...args) {
|
||||
clearTimeout(this.timerId);
|
||||
this.timerId = setTimeout(() => {
|
||||
this.#enqueue(executor, args);
|
||||
}, this.debounceDelay);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user