1. 防抖函数
防抖原理
首先防抖是为了: 防止函数多次调用;
假设一个用户一直在触发某个事件函数, 且每次触发函数的时间间隔小于delay, 那么防抖就会只调用一次;
或者这样理解: 点击的事件函数在一段时间后才执行, 如果这段时间之内再次被点击调用的话, 那么就会重新计算执行时间
案例
典型案例 输入搜索, 一般是输入完成后再进行搜索
防抖函数
function debounce(func, delay= 500) {
// 或者 let delay= delay || 500
// 设置一个定时器
let timer = null;
// 这里返回的函数是每次用户实际调用的防抖函数
return function () {
// 如果已经设定过计时器了就清除掉上一次的定时器
if(timer) clearTimeout(timer)
let that = this;
let args = arguments
// 开始一个新的定时器, 延迟执行用户传入的方法
timer = setTimeout(()=>{
func.apply(that, args)
},delay)
}
}
2. 节流函数
节流原理
如果用户不停的一直触发事件, 那么一开始会执行一次事件, 然后每隔时间间隔wait, 就会立即再次执行该事件
类似就好像英雄联盟的英雄技能释放时间间隔一样, 假设你一直不断的点击某个英雄的一技能, 那么该技能释放后就会进入冷却倒计时假设3秒冷却, 倒计时3秒结束后, 会再次释放技能, 然后再次倒计时3秒后又会释放技能
案例
典型案例: 下拉拖动滚动轴查询显示数据, 隔固定时间delay随着滚动轴下拉就执行一次查询事件, 然后随着一直下拉, 就一直隔固定时间delay执行查询事件
两种方式实现节流函数
定时器方案
function throttle(fn, wait) {
let wait = wait|| 500;
// 设置一个定时器
let timer = null;
return function() {
let that = this;
let args = arguments
if(!timer){
timer = setTimeout(function() {
timer = null
fn.apply(that, args)
},wait)
}
}
}
时间差方案
function throttle(fn, wait) {
let wait = wait|| 500;
// lastTime为上一次触发回调的时间
let lastTime = 0;
return function() {
let that = this;
let args = arguments
// 记录当前函数触发时间
let nowTime = +new Date()
// 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值
if(nowTime-lastTime >= wait) {
lastTime = nowTime
fn.apply(that, args)
}
}
}