事件被触发通过单位时间(delay)后再执行回调,若是在单位时间内又被触发,则从新计时。html
const debounce = (cb, delay = 1000) => { let timer = null; return function (...args) { const context = this; if (timer) clearTimeout(timer); timer = setTimeout(() => { cb.apply(context, args); timer = null; }, delay); } }
若延迟delay设置为1000(默认值),则cb(回调函数)只会在中止触发1s后执行,若是一直不断地触发,则回调函数始终不执行。app
下面是一个简单的使用示例,后续介绍的防抖和节流函数的使用方式也是类似的。dom
const callback = () => { console.log(Math.random()); } const handle = debounce(callback, 1000); window.addEventListener('scroll', handle);
const debounceImmediate = (cb, delay = 1000, immediate = true) => { let timer = null; return function (...args) { const context = this; const execNow = immediate && !timer; if (timer) clearTimeout(timer); timer = setTimeout(() => { cb.apply(context, args); timer = null; }, delay); execNow && cb.apply(this, args); } }
当设置immediate=true(默认值)、delay=1000(默认值)时,第一次触发会当即执行回调函数。后续执行和普通的防抖函数同样,只有在中止触发1s后回调函数才会执行,若是仍是一直不断地触发,则回调函数始终不执行。函数
规定在单位时间(delay)内,只能触发一次函数。若是单位时间内屡次触发函数,只会执行一次回调。this
const throttleUseTimeStamp = (cb, delay = 1000) => { let startTime = Date.now(); return function(...args) { const context = this; const now = Date.now(); if (now - startTime >= delay) { cb.apply(context, args); startTime = Date.now(); } } }
若delay=1000,则在1s内只会执行一次回调函数。spa
const throttleUseTimer = (cb, delay) => { let timer = null; return function(...args) { const context = this; if (!timer) { timer = setTimeout(() => { cb.apply(context, args); timer = null; }, delay); } } }
若delay=1000,则在1s内只会执行一次回调函数。code
const throttleExecMore = function(cb, delay) { let timer = null; let startTime = Date.now(); return function(...args) { const curTime = Date.now(); const remaining = delay - (curTime - startTime); const context = this; timer && clearTimeout(timer); if (remaining <= 0) { // 第一次触发执行 cb.apply(context, args); startTime = Date.now(); } else { // 最后一次触发也会执行 timer = setTimeout(() => { cb.apply(context, args); timer = null; }, remaining); } } }
第一次触发会当即执行回调函数,最后一次触发也会执行一次回调函数。htm
将前面介绍的5种防抖和节流函数分别应用在5个输入框的onChange事件的监听上,delay值统一设置为1000,快速输入1111获得结果以下:
彻底符合咱们前面的分析。blog
若是不加防抖、节流控制,获得结果将是:事件
1 11 111 1111
触发了4次回调函数。
体验防抖和节流 (http://47.92.166.108:3000/blog/index.html#/tutorials/throttle-and-debounce)
体验网址二维码: