Usage:
Some events like resize(), scroll(), keypress(), and mousemove() will frequently trigger callback functions that are bind to that event.
We can use Debounce and Throttle to reduce the frequency.
Application:
1) 防抖(Debounce)
1>Search bar, only after input all the content then send request
2>Validation of phone number, email
3>Resize(), only after user finishes resizing will it compute the window size
2) 节流(Throttle)
1> scroll to load
2> search, search connection (搜索联想功能)
Definition:
防抖(Debounce): execute once within n seconds. If it trigger several times within n seconds, it only occurs once.
节流(Throttle): execute after n seconds. If it is triggered several times within n seconds, re-start counting.
Implementation:
1) Throttle
1> Timestamp: Cannot execute before a certain time
function throttled1(fn, delay = 500) {
let oldtime = Date.now()
return function (...args) {
let newtime = Date.now()
if (newtime - oldtime >= delay) {
fn.apply(null, args)
oldtime = Date.now()
}
}
}
2> setTimeout: set timer to be null, until it finishes previous function
function throttled2(fn, delay = 500) {
let timer = null
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, args)
timer = null
}, delay);
}
}
}
3> Combine two together
function throttled(fn, delay) {
let timer = null
let starttime = Date.now()
return function () {
let curTime = Date.now() // 当前时间
let remaining = delay - (curTime - starttime) // 从上一次到现在,还剩下多少多余时间
let context = this
let args = arguments
clearTimeout(timer)
if (remaining <= 0) {
fn.apply(context, args)
starttime = Date.now()
} else {
timer = setTimeout(fn, remaining);
}
}
}
2) Debounce
1> setTimeout, if trigger again, clear interval and then re-setTimeout
function debounce(func, wait) {
let timeout;
return function () {
let context = this; // 保存this指向
let args = arguments; // 拿到event对象
clearTimeout(timeout)
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
2> If want to apply function immediately
function debounce(func, wait, immediate) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout); // timeout 不为null
if (immediate) {
let callNow = !timeout; // 第一次会立即执行,以后只有事件执行后才会再次触发
timeout = setTimeout(function () {
timeout = null;
}, wait)
if (callNow) {
func.apply(context, args)
}
}
else {
timeout = setTimeout(function () {
func.apply(context, args)
}, wait);
}
}
}
Third-Party Library: ahook
useDebounceFn:
useDebounceEffect: 类似于useEffect, 但是加上了防抖
Comments
Post a Comment