title: 函数的节流与防抖 date: 2019-12-26 14:00:00 tabs:
- 节流
- 防抖
- JavaScript categories: Web前端 urlname: throttle&debounce
在前端开发中,有诸如scroll、resize等高频触发事件,如果给事件绑定一个函数, 那么就会频繁的调用一个函数无数次,这样会造成一些性能上的问题,而节流和防抖则用来限制事件触发后 函数的执行次数。
节流
顾名思义节制水流,如果将事件触发喻为水流,那么函数节流则是节制函数触发次数,
即连续触发事件但是只在n秒钟执行一次函数。主要应用于scroll、resize等事件,比如根据scroll滚轮事件判断元素位置并改变css等。
定时器版
const throttle = (func:Function, wait:number) => {
// 定时器
let executeTimer = null;
return (...args:any[]) => {
if (!executeTimer) {
// 定时器不存在时执行函数
func(...args);
// 赋值定时器
executeTimer = setTimeout(() => {
// wait毫秒后赋值为null
executeTimer = null;
}, wait);
}
}
}
时间戳版
const throttle = (func:Function, wait:number) => {
let previous = 0;
return (...args:any[]) => {
const now = Date.now();
if (now - previous > wait) {
func(...args);
previous = now;
}
}
}
防抖
防抖是指触发事件后在n秒内函数只能执行一次,如果在n秒内又触发了事件,则会重新计算函数执行时间。
就是说只要在n秒内不停触发事件,那么就会不停重置执行时间。
比较经典的例子就是input的onChange事件,往往会有需求要求在用户输入文字后进行数据搜索请求, 如果不进行防抖处理,会出现用户每输入一个字都会触发一次请求,我们可以使用防抖函数避免这种情况, 只要在一定时间内输入文字就不会执行搜索请求,直到用户输入最后一个字的n秒后。
立即执行版
指触发事件后立即执行一次函数,如果在n秒内未再次触发事件,那么则会再次执行一次函数。适用于按钮的防抖等。
const debounce = (func:Function, wait:number) => {
let timer = null;
return (...args:any[]) => {
if (!timer) {
func(...args);
timer = setTimeout(() => {
timer = null;
}, wait);
}
}
}
非立即执行版
非立即执行版的意思是触发事件后函数不会立即执行,而是在n秒后执行,如果在n秒内又触发了事件, 则会重新计算函数执行时间。适用于input的onChange事件。
const debounce = (func:Function, wait:number) => {
let timer = null;
return (...args:any[]) => {
if (!timer) {
timer = setTimeout(() => {
func(...args);
timer = null;
}, wait);
}
}
}