函数节流(throttle)与去抖(debounce)
LiuL0703 opened this issue · comments
LiuL0703 commented
函数去抖(debounce)
函数去抖核心是指:为了不让一个函数单位时间内执行次数太多 从而导致性能问题 限制其在一定时间的连续的函数调用只让其执行一次
应用场景
- resize/scroll 触发统计事件
- 文本输入验证 (输入完成后只验证一次)
- 监听滚动事件判断是否到底部以自动加载更多 (用户停止滚动 判断是否到底部)
基本**
某些代码不可以在没有间断的情况连续重复执行,第一次调用函数创建一个定时器 在指定的时间间隔之后运行代码 当第二次调用该函数时 就会清除前一次的定时器并设置另外一个 如果前一个定时器已经执行过了这个操作就没有意义了 然而如果前一个定时器尚未执行 其实就是将其替换为一个新型的定时器 目的是只有在执行函数的请求停止一段时间后才执行(高程3 P614)
经典实现代码如下:
function debounce(fn,time){
var timer;
return function(){
clearTimeout(timer);
var context = this;
var args = arguments;
timer = setTimeout(function(){
fn.apply(context,args);
},time)
}
}
函数去抖在一段时间只执行一次,而函数节流则是间隔时间段执行 具体如下
函数节流(throttle)
函数节流的核心是指:为了不让一个函数执行的太频繁 减少一些过快的调用 降低函数触发的回调频率
应用场景
- DOM元素的拖拽(mousemove)
- 计算鼠标移动的距离(mousemove)
- Canvas模拟画板(mousemove)
- 搜索联想(keyup)
- 射击游戏的mousedown/keydown(单位时间)
- 监听滚动事件判断是否到底部以自动加载更多 (页面滚动一次就间隔判断一次)
// 定时器实现
function throttle(fn,wait){
var timer;
return function(){
var context = this;
var args = arguments;
if(!timer){
timer = setTimeout(function(){
fn.apply(context,args);
},wait)
}
}
}
// 时间戳实现
function throttle(fn,wait){
var timer;
var prev = 0;
return function(){
var args = arguments;
var now = +new Date();
if(now - prev > wait){
fn.apply(this,args);
prev = now;
}
}
}
// swr
function throttle(fn, wait){
let pending = false;
return (...args) => {
if(pending) return;
pending = true;
fn(...args);
setTimeout(()=> (pending = false), wait);
}
}