浅谈js函数节流和函数防抖
栏目: JavaScript · 发布时间: 6年前
内容简介:函数节流和函数防抖是一种优化方法,可用于减少高频繁触发任务(函数)的执行次数,达到减少资源占用的目的。我们以滚动条的监听事件为例,首先看看使用函数节流和函数防抖前的现象。可以看到随着滚动条的拖动,滚动条拖动的回调函数被频繁触发,在回调比较复杂的时候,频繁触发的回调函数甚至会让网页出现掉帧的情况。而且有些时候,业务上我们并不需要这么高频繁的函数调用。这个时候我们就可以根据业务使用函数节流或函数防抖了。
函数节流和函数防抖是一种优化方法,可用于减少高频繁触发任务(函数)的执行次数,达到减少资源占用的目的。
- 函数节流:任务在指定的间隔时间内只执行一次。
- 函数防抖:只有在任务触发的间隔小于指定的间隔时间,任务才会被执行。
- 区别:在指定时间内,任务执行的次数不同。假设持续触发一个任务1s,且任务间的触发间隔为5ms。 正常情况下 ,该任务触发的次数为1s / 5ms = 200次。 使用函数节流后 (假设指定间隔时间为50ms),50ms内任务只执行一次,那么该任务触发的次数为1s / 50ms = 20次。 使用函数防抖后 (假设指定间隔为50ms),任务触发间隔5ms < 指定间隔50ms,因此在这1s内,该任务执行次数为0次。任务在1s时停止触发后,在1.05s时任务才执行1次。下面我们结合示例来看看函数节流和函数防抖的实现。
我们以滚动条的监听事件为例,首先看看使用函数节流和函数防抖前的现象。
let count = 0;
$(document).scroll(function () {
console.log(`触发了${++count}次!`);
});
复制代码
可以看到随着滚动条的拖动,滚动条拖动的回调函数被频繁触发,在回调比较复杂的时候,频繁触发的回调函数甚至会让网页出现掉帧的情况。而且有些时候,业务上我们并不需要这么高频繁的函数调用。这个时候我们就可以根据业务使用函数节流或函数防抖了。
函数节流
实现
let count = 0;
$(document).scroll(throttle(function () {
console.log(`触发了${++count}次!`);
}, 500));
function throttle(fn, wait) {
let canRun = true;
return function () {
if (!canRun) {
return;
}
canRun = false;
setTimeout(() => {
fn.apply(this, arguments); //让scroll的回调函数的this保持一致
canRun = true;
}, wait);
}
}
复制代码
我们指定了一个时间间隔500ms,规定500ms内滚动事件回调函数只能执行一次。函数节流的实现要点是,使用闭包存储是否可执行标记,如果可执行则设置一个延迟函数,在延迟函数中重置可执行标记。
函数防抖
实现
let count = 0;
$(document).scroll(deBounce(function () {
console.log(`触发了${++count}次!`);
}, 500));
function deBounce(fn, interval) {
let timer = null;
return function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() =>{
fn.apply(this, arguments);
}, interval);
}
}
复制代码
我们指定一个时间间隔500ms,规定滚动事件的回调函数,只有在事件触发的间隔大于500ms时回调函数才执行。函数防抖的实现要点是,使用闭包存储一个延迟函数编号(便于清空延迟函数),在事件触发的时候,清空这个延迟函数,并且设置新的延迟函数。
关于fn.apply(this, arguments)
上文函数节流和函数防抖的实现中,调用fn的时候都是用的fn.apply(this, arguments)调用,而不是fn()直接调用。主要原因是为了fn函数内的this与原本的事件回调函数绑定的this保持一致。 setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致,这些代码中包含的 this 关键字会指向 window (或全局)对象。因此在setTimeout中使用箭头函数(箭头的this绑定的是当前的词法作用域)此时的词法作用域为scroll事件回调函数中绑定的this(jquery中强制this指向dom元素),再将fn函数内的this绑定为这个this。我们以函数防抖为例看看这两种的区别。
$(document).scroll(deBounce(function () {
console.log(this); //#document
}, 500));
function deBounce(fn, interval) {
let timer = null;
return function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() =>{
fn.apply(this, arguments);
}, interval);
}
}
复制代码
$(document).scroll(deBounce(function () {
console.log(this); //Window
}, 500));
function deBounce(fn, interval) {
let timer = null;
return function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() =>{
fn();
}, interval);
}
}
复制代码
$(document).scroll(deBounce(function () {
console.log(this); //Window
}, 500));
function deBounce(fn, interval) {
let timer = null;
return function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
fn.apply(this, arguments);
}, interval);
}
}
复制代码
希望本文对大家有所帮助,互相学习,一起提高。转载请注明原帖。
以上所述就是小编给大家介绍的《浅谈js函数节流和函数防抖》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Algorithmic Beauty of Plants
Przemyslaw Prusinkiewicz、Aristid Lindenmayer / Springer / 1996-4-18 / USD 99.00
Now available in an affordable softcover edition, this classic in Springer's acclaimed Virtual Laboratory series is the first comprehensive account of the computer simulation of plant development. 150......一起来看看 《The Algorithmic Beauty of Plants》 这本书的介绍吧!