Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 11x 54x 54x 11x 11x 14x 14x 14x 13x 13x 13x 13x 14x 32x 14x 14x 29x 29x 29x 29x 28x 28x 28x 28x 28x 28x 28x 28x 28x 5x 28x 1x 14x 14x | import { isNumber, isFunction } from 'support/utils/types';
import { from } from 'support/utils/array';
import { rAF, cAF } from 'support/compatibility/apis';
const clearTimeouts = (id: number | undefined) => {
id && window.clearTimeout(id);
id && cAF!(id);
};
type DebounceTiming = number | false | null | undefined;
export interface DebounceOptions<FunctionToDebounce extends (...args: any) => any> {
/**
* The timeout for debouncing. If null, no debounce is applied.
*/
_timeout?: DebounceTiming | (() => DebounceTiming);
/**
* A maximum amount of ms. before the function will be called even with debounce.
*/
_maxDelay?: DebounceTiming | (() => DebounceTiming);
/**
* Function which merges parameters for each canceled debounce.
* If parameters can't be merged the function will return null, otherwise it returns the merged parameters.
*/
_mergeParams?: (
prev: Parameters<FunctionToDebounce>,
curr: Parameters<FunctionToDebounce>
) => Parameters<FunctionToDebounce> | false | null | undefined;
}
export interface Debounced<FunctionToDebounce extends (...args: any) => any> {
(...args: Parameters<FunctionToDebounce>): ReturnType<FunctionToDebounce>;
_flush(): void;
}
export const noop = () => {}; // eslint-disable-line
/**
* Debounces the given function either with a timeout or a animation frame.
* @param functionToDebounce The function which shall be debounced.
* @param options Options for debouncing.
*/
export const debounce = <FunctionToDebounce extends (...args: any) => any>(
functionToDebounce: FunctionToDebounce,
options?: DebounceOptions<FunctionToDebounce>
): Debounced<FunctionToDebounce> => {
let timeoutId: number | undefined;
let maxTimeoutId: number | undefined;
let prevArguments: Parameters<FunctionToDebounce> | null | undefined;
let latestArguments: Parameters<FunctionToDebounce> | null | undefined;
const { _timeout, _maxDelay, _mergeParams } = options || {};
const setT = window.setTimeout;
const invokeFunctionToDebounce = function (args: IArguments) {
clearTimeouts(timeoutId);
clearTimeouts(maxTimeoutId);
maxTimeoutId = timeoutId = prevArguments = undefined;
// eslint-disable-next-line
// @ts-ignore
functionToDebounce.apply(this, args);
};
const mergeParms = (
curr: Parameters<FunctionToDebounce>
): Parameters<FunctionToDebounce> | false | null | undefined =>
_mergeParams && prevArguments ? _mergeParams(prevArguments, curr) : curr;
const flush = () => {
/* istanbul ignore next */
if (timeoutId) {
invokeFunctionToDebounce(mergeParms(latestArguments!) || latestArguments!);
}
};
const debouncedFn = function () {
// eslint-disable-next-line prefer-rest-params
const args: Parameters<FunctionToDebounce> = from(arguments) as Parameters<FunctionToDebounce>;
const finalTimeout = isFunction(_timeout) ? _timeout() : _timeout;
const hasTimeout = isNumber(finalTimeout) && finalTimeout >= 0;
if (hasTimeout) {
const finalMaxWait = isFunction(_maxDelay) ? _maxDelay() : _maxDelay;
const hasMaxWait = isNumber(finalMaxWait) && finalMaxWait >= 0;
const setTimeoutFn = finalTimeout > 0 ? setT : rAF!;
const mergeParamsResult = mergeParms(args);
const invokedArgs = mergeParamsResult || args;
const boundInvoke = invokeFunctionToDebounce.bind(0, invokedArgs);
// if (!mergeParamsResult) {
// invokeFunctionToDebounce(prevArguments || args);
// }
clearTimeouts(timeoutId);
timeoutId = setTimeoutFn(boundInvoke, finalTimeout as number) as number;
if (hasMaxWait && !maxTimeoutId) {
maxTimeoutId = setT(flush, finalMaxWait as number);
}
prevArguments = latestArguments = invokedArgs;
} else {
invokeFunctionToDebounce(args);
}
};
debouncedFn._flush = flush;
return debouncedFn as Debounced<FunctionToDebounce>;
};
|