123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- function debounce(function_, wait = 100, options = {}) {
- if (typeof function_ !== 'function') {
- throw new TypeError(`Expected the first parameter to be a function, got \`${typeof function_}\`.`);
- }
- if (wait < 0) {
- throw new RangeError('`wait` must not be negative.');
- }
- // TODO: Deprecate the boolean parameter at some point.
- const {immediate} = typeof options === 'boolean' ? {immediate: options} : options;
- let storedContext;
- let storedArguments;
- let timeoutId;
- let timestamp;
- let result;
- function later() {
- const last = Date.now() - timestamp;
- if (last < wait && last >= 0) {
- timeoutId = setTimeout(later, wait - last);
- } else {
- timeoutId = undefined;
- if (!immediate) {
- const callContext = storedContext;
- const callArguments = storedArguments;
- storedContext = undefined;
- storedArguments = undefined;
- result = function_.apply(callContext, callArguments);
- }
- }
- }
- const debounced = function (...arguments_) {
- if (storedContext && this !== storedContext) {
- throw new Error('Debounced method called with different contexts.');
- }
- storedContext = this; // eslint-disable-line unicorn/no-this-assignment
- storedArguments = arguments_;
- timestamp = Date.now();
- const callNow = immediate && !timeoutId;
- if (!timeoutId) {
- timeoutId = setTimeout(later, wait);
- }
- if (callNow) {
- const callContext = storedContext;
- const callArguments = storedArguments;
- storedContext = undefined;
- storedArguments = undefined;
- result = function_.apply(callContext, callArguments);
- }
- return result;
- };
- debounced.clear = () => {
- if (!timeoutId) {
- return;
- }
- clearTimeout(timeoutId);
- timeoutId = undefined;
- };
- debounced.flush = () => {
- if (!timeoutId) {
- return;
- }
- const callContext = storedContext;
- const callArguments = storedArguments;
- storedContext = undefined;
- storedArguments = undefined;
- result = function_.apply(callContext, callArguments);
- clearTimeout(timeoutId);
- timeoutId = undefined;
- };
- return debounced;
- }
- // Adds compatibility for ES modules
- module.exports.debounce = debounce;
- module.exports = debounce;
|