Created
June 23, 2023 14:20
-
-
Save drianoaz/9c56cf85faac134b867ddb2c3b030d91 to your computer and use it in GitHub Desktop.
Simple debounce function using typescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { debounce } from './debounce'; | |
describe('debounce', () => { | |
test('should debounce function calls', () => { | |
jest.useFakeTimers(); | |
const mockFunction = jest.fn(); | |
const delay = 500; | |
const debouncedFunction = debounce(mockFunction, delay); | |
// Call the debounced function multiple times within the delay period | |
debouncedFunction(); | |
debouncedFunction(); | |
debouncedFunction(); | |
// After the delay period, the function should only be called once | |
expect(mockFunction).not.toHaveBeenCalled(); | |
jest.advanceTimersByTime(delay); | |
expect(mockFunction).toHaveBeenCalledTimes(1); | |
jest.useRealTimers(); | |
}); | |
test('should pass arguments to the debounced function', () => { | |
jest.useFakeTimers(); | |
const mockFunction = jest.fn(); | |
const delay = 500; | |
const debouncedFunction = debounce(mockFunction, delay); | |
// Call the debounced function with arguments | |
const arg1 = 'Hello'; | |
const arg2 = 'World'; | |
debouncedFunction(arg1, arg2); | |
// After the delay period, the function should be called with the arguments | |
jest.advanceTimersByTime(delay); | |
expect(mockFunction).toHaveBeenCalledWith(arg1, arg2); | |
jest.useRealTimers(); | |
}); | |
test('should cancel and reset the debounce timer', () => { | |
jest.useFakeTimers(); | |
const mockFunction = jest.fn(); | |
const delay = 500; | |
const debouncedFunction = debounce(mockFunction, delay); | |
// Call the debounced function multiple times within the delay period | |
debouncedFunction(); | |
debouncedFunction(); | |
debouncedFunction(); | |
// Cancel the debounce timer before it expires | |
jest.advanceTimersByTime(delay - 100); | |
debouncedFunction(); | |
// After the delay period, the function should not be called | |
jest.advanceTimersByTime(100); | |
expect(mockFunction).not.toHaveBeenCalled(); | |
jest.useRealTimers(); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type DebouncedFunction<T extends unknown[]> = (...args: T) => void; | |
/** | |
* Creates a debounced function that delays the execution of the provided function `func` | |
* until a specified delay has passed without any further function calls. Only the last | |
* function call within the delay period will be executed. | |
* | |
* @template T - The type of the original function's arguments. | |
* @param {(...args: T) => void} func - The original function to be debounced. | |
* @param {number} delay - The delay in milliseconds. | |
* @returns {DebouncedFunction<T>} - The debounced function. | |
* | |
* @example | |
* // Example usage of debounce function | |
* | |
* function saveChanges() { | |
* console.log('Saving changes...'); | |
* // Perform the actual save operation | |
* } | |
* | |
* const debouncedSaveChanges = debounce(saveChanges, 1000); | |
* | |
* // Simulating rapid calls to the debounced function | |
* debouncedSaveChanges(); // No immediate call | |
* debouncedSaveChanges(); // No immediate call | |
* debouncedSaveChanges(); // No immediate call | |
* | |
* // After 1000ms of inactivity, 'Saving changes...' will be logged and saveChanges will be invoked. | |
**/ | |
export function debounce<T extends unknown[]>( | |
func: (...args: T) => void, | |
delay: number, | |
): DebouncedFunction<T> { | |
let timeoutId: ReturnType<typeof setTimeout> | undefined; | |
return function (...args: T) { | |
clearTimeout(timeoutId); | |
timeoutId = setTimeout(() => { | |
func(...args); | |
}, delay); | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment