<>前言

* 前段时间群友说面试的时候老是分不清防抖和节流。
* 其实防抖和节流不仅仅在面试中会让大家手写,在实际项目中也可以起到性能优化的作用,所以还是很有必要掌握的。
* 接下来我就用一杯茶的时间带大家彻底学会手写防抖和节流。
<>防抖

<>举个例子

*
我们先抛开概念不谈,其实在生活中也有很多防抖的例子:

比如你现在使用的电脑,在不使用后一段时间自动休眠 当你再次使用的时候重新激活,并开始你设置的时间倒计时10分钟
在这10分钟内你继续使用电脑又会重新开始倒计时10分钟 当你最后一次使用电脑并离开时重新倒计时10分钟过去了,电脑就休眠了

*
这其实这就是防抖的基本概念了~说白了就是在一段时间只执行一次,也就是我们上面的电脑只打开这一次。

*
我们上面的使用电脑可以理解为触发事件,而与我上面标注的setTimeout和clearTimeout其实就是防抖的主要要素了。

*
当然上面的是生活中的例子,那我们在我们的日常开发中其实也经常用到,比如我们调整页面的大小,验证表单某个字段是否重复时发生请求次数控制,防止表单多次提交等。

<>手写防抖

*
说了这么多,相信大家大概理解了防抖的概念,那我们现在来实现一个防抖吧,假设我们要点击一个按钮新增一条信息,当然我们不希望每次点击都调用接口新增,我们希望多次点击只新增一次,这时候我们该怎么写呢?

* 首先我们先简单的模拟一个按钮被点击的过程。 let addBtn=document.getElementById("add") function
addOne(){ console.log('添加数据') } addBtn.addEventListener("click",addOne)
* 因为我们需要对执行的事件进行处理所以接下来我们需要封装一下addOne函数。 let addBtn=document.getElementById(
"add") function addOne(){ console.log('添加数据') } function debounce(fun){ return
function(){ fun() } } addBtn.addEventListener("click",debounce(addOne))
* 上面我们用闭包处理了一下addOne函数,接下来我们需要添加一个延时器setTimeout来倒计时,当我们点击按钮后过2s再执行。 function
debounce(fun,time){ return function(){ setTimeout(()=>{ fun() },time) } }
addBtn.addEventListener("click",debounce(addOne,2000)
* 现在延时的目的是达到了但是每次点击都会新增一个新的setTimeout但是并不能达到我们多次点击只执行一次的效果。
* 这时候就需要clearTimeout登场了,我们需要在我们点击了按钮后也就是debounce执行时要先把之前的setTimeout先清除再重新计时。
function debounce(fun,time){ let timer return function(){ clearTimeout(timer)
timer=setTimeout(()=>{ fun() },time) } } addBtn.addEventListener("click"
,debounce(addOne,2000)
* 现在我们的一个防抖功能就完成了,但是这还没完,如果我们在addOne()打印this会发现我们这样执行的this是指向Window的。
*
这当然不是我们所希望的,我们需要使用apply来改变this指向,再者就是我们需要考虑到执行函数的参数,因为不同的函数肯定会有不同的参数传入,对于参数我们可以使用arguments处理。
function debounce(fun,time){ let timer return function(){ clearTimeout(timer)
let args = arguments timer=setTimeout(()=>{ fun.apply(this,args) },time) } }
* 这样我们的防抖函数就手写完成了,看起来其实也并不难。
* 总而言之防抖就是在不断的操作中(输入、点击等)最终只执行一次的一种提高性能的方法。
<>结语

好了暂时先到这,节流明天再总结

一句话总结,若时间周期为5秒,防抖是5秒内重复的触发会导致重新计时,直到5秒内没有重复触发函数才会执行,节流是5秒内只会执行第一次触发的函数,重复的触发无效。

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:766591547
关注微信