debounce 防抖
概述
事件在一段时间内连续被触发,换句话,如果每次触发的时间间隔小于delay
,事件的处理不会执行。【多次操作变成一次】
实现
有两种情况
- 用户触发事件,就立即执行,后面如果用户连续(每次触发时间小于
dealy
)触发,后续都不会再执行事件处理 - 用户触发事件,如果距离上次触发事件时间超过
delay
,则执行事件处理
function debounce(fn, delay, immediate) {
let timer = null;
return (...arg) => {
if(timer) {
clearTimeout(timer);
}
if(immediate) {
const canDo = !timer;
timer = setTimeout(() =< {
clearTimeout(timer);
timer = null;
}, delay);
if(canDo) {
fn.call(this, ...arg);
}
}
else {
timer = setTimeout(() => {
fn.call(this, ...arg);
clearTimeout(timer);
timer = null;
}, delay);
}
}
}
应用场景
根据用户输入,实时搜索 在这种场景下,如果用户输入输入就触发搜索是不合理,我们只需要判断用户是输入完成(例如用户间隔500ms,没有再输入内容,判断输入完成),此时再出发搜索可以了。
window的resize 我们在使用echart时,如果窗口变化,我们是需要resize画布的,用户不断改变可视区域大小,我们其实并不需要每监听到window的resize就改变画布,只需要在最后一次再进行resize画布就行。
throttle 节流
概述
节约资源,用户不断触发事件,如果距离上次事件执行超过delay
,这再执行一次事件处理
【一定时间内只调用一次】
实现
function throttle(fn, delay, immedate = true) {
let pre = 0;
let timer = null;
return (...arg) => {
const nowTime = new Date().getTime();
if(pre + delay <= nowTime) {
if(immedate) {
pre = nowTime;
fn.call(this, ...arg);
}
else {
timer = setTimeout(() => {
fn.call(this, ...arg);
clearTimeout(timer);
timer = null;
}, delay);
}
}
}
}
应用
用户点击按钮
用户不断点击按钮,如果在一段时间内,事件处理已经执行过一次了,我们就无需在执行