防抖或节流:都是为了限制业务逻辑函数的执行次数
1.防抖debounce
防抖即通过setTimeOut的方式,将多次触发变为一次触发
什么是函数防抖
概念:函数防抖(debounce),就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间。
为什么需要函数防抖
前端开发过程中,有一些事件,常见的例如,onresize,scroll,mousemove ,mousehover 等,会被频繁触发(短时间内多次触发),不做限制的话,有可能一秒之内执行几十次、几百次,如果在这些函数内部执行了其他函数,尤其是执行了操作 DOM 的函数(浏览器操作 DOM 是很耗费性能的),那不仅会浪费计算机资源,还会降低程序运行速度,甚至造成浏览器卡死、崩溃。这种问题显然是致命的。
除此之外,短时间内重复的 ajax 调用不仅会造成数据关系的混乱,还会造成网络拥塞,增加服务器压力,显然这个问题也是需要解决的。
所以说需要通过防抖函数来限制业务逻辑函数里面的逻辑
接下来看防抖函数怎么写吧!
首先看代码,submit函数即我们自己的业务逻辑函数,里面可以自由添加逻辑!
先看18行,注意addEventListener函数的第二个参数是传函数的,but
然后如果函数想传参的话,可以用一个匿名函数包裹着
这样一来,this和arguments就清晰了,箭头函数内部是没有this/arguments的;是拿外部函数的!
所以说为什么27行的this是window,就是因为addEventListener时函数自调用了,也就是全局window调用;
而返回的函数就是inp调用的了;(因为debounce函数的执行结果就是一个函数),相当于直接在那里放了个fn;
后面没有括号那种,也就是不自己调用;
所以38行的this是指向inp的!
这样通过箭头函数,传入的fn就能通过call方法拿到事件对象和调用者的this;
这里的思路是:
如果是第一次点击,则触发fn调用;而是不是第一次触发则根据t的值决定,如果重复点击,则t有值,肯定不是第一次触发;
t转化为布尔值null则是false;有值则为true;
**注意定义firstClick一定要写在里面;**因为到时候null在里面变为null外面是获取不到里面的;而里面可以获取外面
然后:
如果是第一次点击,直接触发没毛病;
如果重复点击几次,则触发第一次后,debounce函数不断执行,定时器不断刷新,t永远有值,所以只会执行第一次!
如果过一段时间后,t变成了null,所以又变成了第一次点击!
2.节流throttle
一段时间内,减少触发频率,过一段时间执行一次
和防抖类似,但是不一样;防抖是连续的点击,只会触发一次;而节流是延迟一段时间就会执行一次,不断重复!
防抖的立即执行与非立即执行
立即执行与非立即执行顾名思义;上面的防抖是立即执行的!
非立即执行,即点击触发定时器,不断点击则不断触发;直到最后一次点击,等待delay时间后执行函数!
立即执行也就是定义了一个变量来判断是不是第一次点击,是的话则触发,然后t = null;算是非立即执行的进阶
加入一个布尔值来判断需要哪种;然后合并代码
节流的另一种写法:
这里的思路是,第一次点击flag为true,进入if,然后flag = false;再delay时间后会执行函数,然后flag = true;注意有定时器会放到异步队列,这个后执行!
然后此时若不断点击,则会触发return function那块,注意let flag = true是不会触发的,这个一开始window就自调用了;
不断点击后,等setTimeOut执行完成则继续进入if,然后又flag = false,进入定时器…