节流:在一定时间内触发一次(以3秒为例,比如在3秒内频繁操作一个方法,只触发一次)
防抖:在一定时间之后触发(以3秒为例,比如频繁点击某个按钮,每次都会重新计算,在3秒后才执行一次)
应用场景
防抖在连续的事件,只需触发一次回调的场景有:
- 搜索框搜索输入。只需用户最后一次输入完,再发送请求
- 机号、邮箱验证输入检测
- 窗口大小resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
节流在间隔一段时间执行一次回调的场景有:
- 滚动加载,加载更多或滚到底部监听
- 搜索框
节流
时间戳与定时器相结合,更加精确
const throttled = (fn, delay) => {
let timer = null
let startTime = Date.now()
return function () {
const currentTime = Date.now()
const remaining = delay - (currentTime - startTime)
const ctx = this
const args = arguments
clearTimeout(timer)
if (remaining <= 0) {
fn.applay(ctx, args)
startTime = Date.now()
} else {
timer = setTimeout(fn, remaining)
}
}
}
防抖
如果需要立即执行,可加入第三个参数immediate用于判断
const 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);
}
}
}