let times = 0 let container = document.querySelector("#container") let button = document.querySelector("#cancel")
functiongetUserAction() { // do some thing container.innerHTML = `run ${++times} time(s).` }
/** * * @param {function(): *} func * @param {number} wait * @param {boolean} immediate * @returns {function(): *} */ functiondebounce(func, wait, immediate) { let timer // start a new timer every time it is triggered let result // get the return from func | undefined(only if the immediate is true will return a value)
let debounced = function () { let context = this// current context let args = arguments// events
if (timer) { clearTimeout(timer) } if (immediate) { // check whether it is called immediately let callNow = !timer // callNow is always false unless the timer is null timer = setTimeout(() => { timer = null// set the timer null after wait time }, wait) if (callNow) { // means timer is null now, then call func result = func.apply(context, args) } } else { timer = setTimeout(() => { // 1. bind the `this` to `<div id="container"></div>` // 2. get the `event` func.apply(context, args) }, wait) }
return result }
debounced.cancel = function () { // to cancel the debounce clearTimeout(timer) timer = null// reset to null }
return debounced }
let userAction = debounce(getUserAction, 5000, true) // get the function `debounced`
container.onmousemove = userAction button.onclick = function () { userAction.cancel() }
let times = 0 let container = document.querySelector("#container") let button = document.querySelector("#cancel")
functiongetUserAction() { // do some thing container.innerHTML = `run ${++times} time(s).` }
functionthrottle( func, wait, options = { leading: true, // run immediately trailing: true, // run after wait time } ) { let timer let context let args let previous = 0
let later = function () { previous = !options.leading ? 0 : newDate().getTime() timer = null func.apply(context, args) context = args = null }
let throttled = function () { let now = newDate().getTime() if (!previous && !options.leading) previous = now let remaining = wait - (now - previous) context = this args = arguments
if (remaining <= 0 || remaining > wait) { if (timer) { clearTimeout(timer) timer = null }