2024-01-01 21:11:32 +00:00
|
|
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
2022-03-01 04:25:50 +00:00
|
|
|
// This module is browser compatible.
|
2021-07-10 12:30:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A debounced function that will be delayed by a given `wait`
|
|
|
|
* time in milliseconds. If the method is called again before
|
|
|
|
* the timeout expires, the previous call will be aborted.
|
|
|
|
*/
|
|
|
|
export interface DebouncedFunction<T extends Array<unknown>> {
|
|
|
|
(...args: T): void;
|
|
|
|
/** Clears the debounce timeout and omits calling the debounced function. */
|
|
|
|
clear(): void;
|
|
|
|
/** Clears the debounce timeout and calls the debounced function immediately. */
|
|
|
|
flush(): void;
|
2022-11-25 11:40:23 +00:00
|
|
|
/** Returns a boolean whether a debounce call is pending or not. */
|
2021-07-10 12:30:34 +00:00
|
|
|
readonly pending: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a debounced function that delays the given `func`
|
|
|
|
* by a given `wait` time in milliseconds. If the method is called
|
|
|
|
* again before the timeout expires, the previous call will be
|
|
|
|
* aborted.
|
|
|
|
*
|
2024-05-22 05:08:36 +00:00
|
|
|
* @example Usage
|
2024-09-19 23:29:31 +00:00
|
|
|
* ```ts ignore
|
2024-04-29 02:57:30 +00:00
|
|
|
* import { debounce } from "@std/async/debounce";
|
2021-07-10 12:30:34 +00:00
|
|
|
*
|
2024-06-14 10:13:44 +00:00
|
|
|
* const log = debounce(
|
|
|
|
* (event: Deno.FsEvent) =>
|
|
|
|
* console.log("[%s] %s", event.kind, event.paths[0]),
|
|
|
|
* 200,
|
2021-07-10 12:30:34 +00:00
|
|
|
* );
|
2024-06-14 10:13:44 +00:00
|
|
|
*
|
|
|
|
* for await (const event of Deno.watchFs("./")) {
|
|
|
|
* log(event);
|
|
|
|
* }
|
2022-11-25 11:40:23 +00:00
|
|
|
* // wait 200ms ...
|
|
|
|
* // output: Function debounced after 200ms with baz
|
2021-07-10 12:30:34 +00:00
|
|
|
* ```
|
|
|
|
*
|
2024-05-22 00:40:43 +00:00
|
|
|
* @typeParam T The arguments of the provided function.
|
2024-05-22 05:08:36 +00:00
|
|
|
* @param fn The function to debounce.
|
|
|
|
* @param wait The time in milliseconds to delay the function.
|
|
|
|
* @returns The debounced function.
|
2021-07-10 12:30:34 +00:00
|
|
|
*/
|
|
|
|
// deno-lint-ignore no-explicit-any
|
|
|
|
export function debounce<T extends Array<any>>(
|
|
|
|
fn: (this: DebouncedFunction<T>, ...args: T) => void,
|
|
|
|
wait: number,
|
|
|
|
): DebouncedFunction<T> {
|
|
|
|
let timeout: number | null = null;
|
|
|
|
let flush: (() => void) | null = null;
|
|
|
|
|
2022-08-24 01:21:57 +00:00
|
|
|
const debounced: DebouncedFunction<T> = ((...args: T) => {
|
2021-07-10 12:30:34 +00:00
|
|
|
debounced.clear();
|
2022-08-24 01:21:57 +00:00
|
|
|
flush = () => {
|
2021-07-10 12:30:34 +00:00
|
|
|
debounced.clear();
|
|
|
|
fn.call(debounced, ...args);
|
|
|
|
};
|
2024-07-12 04:29:44 +00:00
|
|
|
timeout = Number(setTimeout(flush, wait));
|
2021-07-10 12:30:34 +00:00
|
|
|
}) as DebouncedFunction<T>;
|
|
|
|
|
2022-08-24 01:21:57 +00:00
|
|
|
debounced.clear = () => {
|
2021-07-10 12:30:34 +00:00
|
|
|
if (typeof timeout === "number") {
|
|
|
|
clearTimeout(timeout);
|
|
|
|
timeout = null;
|
|
|
|
flush = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-08-24 01:21:57 +00:00
|
|
|
debounced.flush = () => {
|
2021-07-10 12:30:34 +00:00
|
|
|
flush?.();
|
|
|
|
};
|
|
|
|
|
|
|
|
Object.defineProperty(debounced, "pending", {
|
|
|
|
get: () => typeof timeout === "number",
|
|
|
|
});
|
|
|
|
|
|
|
|
return debounced;
|
|
|
|
}
|