Skip to content

Instantly share code, notes, and snippets.

@danielhaim1
Last active March 31, 2023 09:04
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 danielhaim1/11e5412ef4ce8975d3cc8429549988ef to your computer and use it in GitHub Desktop.
Save danielhaim1/11e5412ef4ce8975d3cc8429549988ef to your computer and use it in GitHub Desktop.
Improved debounce function for JavaScript

Debounce Method

This function creates a debounced version of a function that delays invoking the original function until after a specified amount of time has elapsed since the last invocation of the debounced function.

const debouncedFunc = methodDebounce(func, wait, immediate, context);

Parameters

  • func (required): The function to debounce.
  • wait (required): The number of milliseconds to wait before invoking the function.
  • immediate (optional): Whether to invoke the function on the leading edge (true) or trailing edge (false) of the wait interval. Defaults to false.
  • context (optional): The execution context to use for the function. Defaults to null.

Returns:

  • A debounced version of the original function.

Examples

// Basic functionality
const func1 = () => console.log('Function 1 called');
const debouncedFunc1 = methodDebounce(func1, 100);

debouncedFunc1(); // function should not be called yet

setTimeout(() => {
  debouncedFunc1(); // function should be called once
}, 200);

// Immediate execution
const func2 = () => console.log('Function 2 called');
const debouncedFunc2 = methodDebounce(func2, 100, true);

debouncedFunc2(); // function should be called immediately

// Custom execution context
const context = { foo: 'bar' };
const func3 = function() { console.log(this.foo); };
const debouncedFunc3 = methodDebounce(func3, 100, false, context);

debouncedFunc3(); // function should log 'bar'

// Canceling debounced function
const func4 = () => console.log('Function 4 called');
const debouncedFunc4 = methodDebounce(func4, 100);

debouncedFunc4();
debouncedFunc4.cancel(); // function should not be called

// Asynchronous function support
const asyncFunc = () => new Promise(resolve => setTimeout(() => {
  console.log('Function 5 called');
  resolve('test');
}, 100));
const debouncedFunc5 = methodDebounce(asyncFunc, 100);

debouncedFunc5(); // function should be called once after 100ms

Window Events

// Test debounced window resize event
window.addEventListener('resize', improvedDebounce(() => {
  console.log('Window resized!');
}, 100));

// Test debounced window scroll event
window.addEventListener('scroll', improvedDebounce(() => {
  console.log('Window scrolled!');
}, 100));

// Test debounced window mousemove event
window.addEventListener('mousemove', improvedDebounce((event) => {
  console.log(`Mouse moved to (${event.clientX}, ${event.clientY})!`);
}, 100));

// Test debounced window click event
window.addEventListener('click', improvedDebounce((event) => {
  console.log(`Clicked at (${event.clientX}, ${event.clientY})!`);
}, 100));
/**
* Creates a debounced function that delays invoking func until after wait milliseconds have elapsed
* since the last time the debounced function was invoked. If immediate is true, func is invoked on
* the leading edge instead of the trailing edge of the wait interval. Optionally, a custom execution
* context can be specified with the context parameter.
*
* @param {function} func - The function to debounce.
* @param {number} wait - The number of milliseconds to wait before invoking the function.
* @param {boolean} immediate - Whether to invoke the function on the leading edge (true) or trailing edge (false) of the wait interval. Defaults to false.
* @param {*} context - The execution context to use for the function. Defaults to null.
* @returns {function} - The debounced function.
*/
function methodDebounce(func, wait, immediate = false, context = null) {
let timeout;
let result;
const debounced = function executedFunction(...args) {
const execute = function() {
result = func.apply(context, args);
timeout = null;
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(execute, wait);
if (callNow) {
result = func.apply(context, args);
}
return result;
};
debounced.cancel = function() {
clearTimeout(timeout);
};
debounced.result = function() {
return result;
};
return debounced;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment