函数防抖和节流

34次阅读

共计 1449 个字符,预计需要花费 4 分钟才能阅读完成。

函数防抖和节流
防抖
对于触发非常频繁又没有必要每次都执行的事件,希望合并到一次去执行;
实现思路:
事件触发后,在规定的时间范围内如果事件重复触发,那么忽略之前触发的事件,并且重新开始计时,直到某一次事件触发后大于规定时间,我们才执行需要执行的代码段(函数);
看起来就像是只执行了用户快速操作的最后一次事件;
代码实现:
var debounce = function(fn, delayTime) {
var timeId;
return function() {
var context = this, args = arguments;
timeId && clearTimeout(timeout);
timeId = setTimeout(function{
fn.apply(context, args);
}, delayTime)
}
}
简单分析:
利用闭包保存一个 setTimeout 的 id,如果在 delayTime 内闭包中的函数再次执行,会立刻 clear 掉上一次的延时回调,生成一个新的延时回调;如果超过 delayTime 没有再次执行闭包中的函数,那延时回调就会被执行,这样才算是真正执行了需要执行的事件。
应用场景:

给按钮加函数防抖防止表单多次提交。
对于输入框连续输入进行 AJAX 验证时,用函数防抖能有效减少请求次数。
判断 scroll 是否滑到底部,滚动事件 + 函数防抖

节流
对于触发非常频繁的事件,在规定时间间隔后才能执行,在规定时间间隔内触发的事件会被忽略,但是不会重新开始计时;
实现思路:
规定一个时间,一次触发后,在规定时间内触发的事件都忽略,超过规定时间后可以重新执行触发的事件;
代码实现:(两种)
时间戳
var throttle = (fn, delayTime) => {
var _start = Date.now();
return function() {
var _now = Date.now(), context = this, args = arguments;
if(_now – _start >= delayTime) {
fn.apply(context, args);
_start = Date.now();
}
}
}
简单分析:
先设定一个初始时间,然后每次执行闭包内的函数都与当前时间做比较,如果小于 delayTime,什么也不做,忽略该次事件,如果大于 delayTime,执行回调函数 fn,重置初始时间;
定时器
var throttle = function(fn, delayTime) {
var flag;
return function() {
var context = this, args = arguments;
if(!flag) {
fn.apply(context, args);
flag = setTimeout(function() {
flag = false;
}, delayTime);
}
}
}
简单分析:
通过设定一个标志位,通过标志位判断是否可以执行回调函数,在延时函数中执行回调的同时将标志位置为可再次执行,这样就保证了在规定时间之后能再次执行需要的回调函数;
应用场景:

游戏中的刷新率
DOM 元素拖拽
Canvas 画笔功能

防抖和节流区别

防抖是把之前频繁的事件触发都放到某一次停顿时触发,可以理解为执行最后一次(并不准确);节流则是执行完一次以后等待一段时间之后才能再次执行,可以理解为第一次;这意味着防抖执行的是最新的,而节流在等待中如果事件有更新是不会执行的,会被忽略,这两者应用场景不同;
防抖适合多次事件一次响应的情况;
节流适合大量事件按时间做平均分配触发。

参考:
十分钟学会防抖和节流
轻松理解 JS 函数节流和函数防抖

正文完
 0