@v4fire/core
Version:
V4Fire core library
103 lines (80 loc) • 2.15 kB
text/typescript
/*!
* V4Fire Core
* https://github.com/V4Fire/Core
*
* Released under the MIT license
* https://github.com/V4Fire/Core/blob/master/LICENSE
*/
import extend from 'core/prelude/extend';
/** @see [[Function.debounce]] */
extend(Function.prototype, 'debounce', function debounce(this: AnyFunction, delay: number = 250): AnyFunction {
const
// eslint-disable-next-line @typescript-eslint/no-this-alias
fn = this;
let
timer;
return function wrapper(this: unknown, ...args: unknown[]): void {
const
cb = () => fn.apply(this, args);
if (delay === 0) {
clearImmediate(timer);
timer = setImmediate(cb);
} else {
clearTimeout(timer);
timer = setTimeout(cb, delay);
}
};
});
/** @see [[FunctionConstructor.debounce]] */
extend(Function, 'debounce', (fn: AnyFunction | number, delay?: number) => {
if (Object.isNumber(fn)) {
delay = fn;
return (fn) => Function.debounce(fn, delay);
}
return fn.debounce(delay);
});
/** @see [[Function.throttle]] */
extend(Function.prototype, 'throttle', function throttle(
this: AnyFunction,
delayOrOpts?: number | ThrottleOptions
): AnyFunction {
let
opts: ThrottleOptions = {};
if (Object.isNumber(delayOrOpts)) {
opts.delay = delayOrOpts;
} else {
opts = {...delayOrOpts};
}
opts.delay = opts.delay ?? 250;
const
// eslint-disable-next-line @typescript-eslint/no-this-alias
fn = this;
let
lastArgs,
timer;
return function wrapper(this: unknown, ...args: unknown[]): void {
lastArgs = args;
if (timer === undefined) {
fn.apply(this, lastArgs);
const cb = () => {
timer = undefined;
if (!opts.single && lastArgs !== args) {
wrapper.apply(this, lastArgs);
}
};
if (opts.delay === 0) {
timer = setImmediate(cb);
} else {
timer = setTimeout(cb, opts.delay);
}
}
};
});
/** @see [[FunctionConstructor.throttle]] */
extend(Function, 'throttle', (fn: AnyFunction | number, delayOrOpts?: number | ThrottleOptions) => {
if (!Object.isFunction(fn)) {
delayOrOpts = fn;
return (fn) => Function.throttle(fn, Object.cast(delayOrOpts));
}
return fn.throttle(Object.cast(delayOrOpts));
});