Skip to content

Instantly share code, notes, and snippets.

@intrnl
Last active January 5, 2020 05:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save intrnl/fbb5bf27bd4a46229010217c3ab5037b to your computer and use it in GitHub Desktop.
Save intrnl/fbb5bf27bd4a46229010217c3ab5037b to your computer and use it in GitHub Desktop.
export function debounce<F extends ((...args: any) => any)> (
fn: F,
ms: number
) {
/**
* Not the correct type, because of these conflicts:
* - Node's setTimeout returns a `Timeout` object
* - Browser's setTimeout returns a `number`
*
* TypeScript doesn't provide an option to specifically exclude certain type
* declarations, this is bothersome particularly in monorepo scenarios.
* See microsoft/TypeScript#18588 and #31148 for progress on this.
*/
let timeout: any;
let resolves: ((result: any) => void)[] = [];
return function (...args: any) {
clearTimeout(timeout);
timeout = setTimeout(() => {
const result = fn(...args);
resolves.forEach((resolve) => resolve(result));
resolves = [];
}, ms);
return new Promise((resolve) => {
resolves.push(resolve);
})
} as ((...args: Parameters<F>) => Promise<ReturnType<F>>);
}
export function mDebounce (ms: number) {
return function (
target: Object,
propertyKey: string | symbol,
descriptor: PropertyDescriptor
) {
const map = new WeakMap;
const originalMethod = descriptor.value;
descriptor.value = function (...args: any) {
let debounced = map.get(this);
if (!debounced) {
debounced = debounce(originalMethod.bind(this), ms);
map.set(this, debounced);
}
return debounced(...args);
}
return descriptor;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment