持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情
防抖和节流的定义
什么是防抖?
-
当事件触发时,相应的函数并不会立即触发,而是会等待一定的时间;
-
当事件密集触发时,函数的触发会被频繁的推迟;
-
只有等待了一段时间也没有事件触发,才会真正的执行响应函数;
总结来说就是:只有在某个时间内,没有再次触发某个函数时,才真正的调用这个函数。
什么是节流
-
当事件触发时,会执行这个事件的响应函数;
-
如果这个事件会被频繁触发,那么节流函数会按照一定的频率来执行函数;
-
不管在这个中间有多少次触发这个事件,执行函数的频繁总是固定的;
总结来说:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
应用场景
防抖应用场景
-
输入框中频繁的输入内容,搜索或者提交信息;
如果这里不做防抖处理,那么输入一个信息,就会马上提交查询,就造成频繁的发送了很多请求,增大了服务器压力。
-
频繁的点击按钮,触发某个事件;
点击按钮一般用来做提交表单,提交数据的操作,如果没有防抖那么也同样的发送了N多不必要的请求。
-
监听浏览器滚动事件,完成某些特定操作;
-
用户缩放浏览器的resize事件;
节流应用场景
-
监听页面的滚动事件;
-
鼠标移动事件;
鼠标移动事件会不停的触发,来响应做一些操作,那么我们不应该让他一直触发,这样太影响性能,这时候依赖节流就可以避免过于频繁的操作。
-
用户频繁点击按钮操作;
-
游戏中的一些设计;
比如飞机大战的游戏中会有这样的设定,即使按下的频率非常快,子弹也会保持一定的频率来发射; 比如1秒钟只能发射一次,即使用户在这1秒钟按下了10次,子弹会保持发射一颗的频率来发射;但是事件是触发了10次的,响应的函数只触发了一次。
防抖和节流的实现
防抖实现
使用了闭包和call函数来实现
//防抖函数
function debounce(fn,delay){
let time = null;// 创建一个标记用来存放定时器的返回值
return function(){
// 每当用户输入的时候把前一个 setTimeout clear 掉
if(time !== null){
clearTimeout(time)
}
// 然后又创建一个新的 setTimeout, 这样就能保证interval 间隔内如果时间持续触发,就不会执行 fn 函数
time = setTimeout(()=>{
fn.call(this,arguments);
},delay)
}
}
节流实现
//节流函数:n段时间内只执行第一次
function throttle(fn,delay){
let flag = true;// 通过闭包保存一个标记
return function(){
// 在函数开头判断标记是否为true,不为true则return
if (!flag) return;
// 立即设置为false
flag = false;
// 将外部传入的函数的执行放在setTimeout中
setTimeout(() => {
// 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。
// 当定时器没有执行的时候标记永远是false,在开头被return掉
fn.apply(this, arguments);
flag = true;
}, delay);
}
}
总结
函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数。 而函数防抖只是在最后一次事件后才触发一次函数,同时掌握好闭包和call函数能帮我们更好理解和实现。