Debounce a function
/**
* Creates a debounced monad to allow a method to be called
* many times, but only execute after N seconds has elapsed
*
* @param {Function} func Method to call
* @param {Number} wait Timeout, in milliseconds
* @param {Boolean} [immediate] Optionally skip the wait
* @return {Function} Debounced monad that can be called multiple times
*/
export function debounce(func, wait, immediate) {
let timeout
return function (...args) {
clearTimeout(timeout)
timeout = setTimeout(() => {
timeout = null
if (!immediate) func.apply(this, args)
}, wait)
if (immediate && !timeout) func.apply(this, [...args])
}
}
// Example
const prom = (a, b) => new Promise(resolve => {
setTimeout(() => resolve(a + b), 1000)
})
const fun = async (a, b) => {
try {
const res = await prom(a, b)
console.log(a, '+', b, '=', res)
}
catch (e) {
return null
}
}
const funDebounced = debounce(fun, 600)
funDebounced(1, 2)
funDebounced(3, 4)
funDebounced(5, 6)
funDebounced(7, 8)
funDebounced(9, 10)
// Outputs: 9 '+' 10 '=' 19