防抖与节流区别以及使用场景

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了防抖与节流区别以及使用场景相关的知识,希望对你有一定的参考价值。

参考技术A 另附内容:

_.throttle(func, [wait=0], [options=])

原网址: https://segmentfault.com/a/1190000018445196
目的:当多次执行某一动作,进行函数调用次数的限制,节省资源
防抖:在事件触发n秒后执行函数,如果在n秒内再次出发,重新计时
节流:当多次执行某一动作,每个一段时间,只执行一次函数。
防抖函数(普通)

需要将timer封装到debounce中,如果调用的fn有参数需要处理

节流(2种方式setTimeout 或者 new Date())
//防抖比节流严格,防抖在一定时间操作后只执行一次。节流在一定时间操作,可每隔n秒执行一次
setTimeout方式

new Date方式

连续的事件,只需触发一次回调的场景有:

搜索框搜索输入。只需用户最后一次输入完,再发送请求
手机号、邮箱验证输入检测(change、input、blur、keyup等事件触发,每次键入都会触发)
窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
鼠标的mousemove、mouseover
导航条上,用户不停的在导航区域滑动相当于

间隔一段时间执行一次回调的场景有:

滚动加载,加载更多或滚到底部监听,window.onscroll和滑到底部自动加载更多
谷歌搜索框,搜索联想功能
高频点击提交,表单重复提交

js防抖与节流

防抖与节流是个老生常谈的问题了,实际工作中多多少少也会有应用的场景,并且也是面试中的高频考点,但是很多人对这两个概念是有点傻傻分不清楚,作出的答案很难让人满意。

很长一段时间里面我自己也是这样,当需要用到防抖和节流,都是直接到网上一搜,copy下来就用了,貌似也没出啥问题。

但是如果让你自己手写一个,你能很利索的写出没问题的代码吗,估计没那么简单了。

要了解这两个的作用以及区别,得先搞清楚这两货到底是干嘛的,解决了啥问题,什么情况下改用哪个,这样子,自己头脑就不会混乱。

其实仔细想想,两个的原理是比较简单的

防抖和节流的目的都是减少时间触发的次数,但是两者还是有一点点区别

防抖:就是事件整合,你一直点一个按钮,如果不做处理的话,你点一次,就触发一次事件,如果你恶意瞎点击,那我就每次都得响应,很浪费资源并且容易导致崩溃,正常情况下,我们是你点一次有一个小间隔,如果下次点击的时间超过了这个间隔,那么就触发事件,否则等待,这个间隔时间其实就相当于是一个确认的过程。

 1   function debounce(fn,delay) {
 2         var timeout = null; // 创建一个标记用来存放定时器的返回值
 3         return function (e) {
 4             // 每当用户输入的时候把前一个 setTimeout clear 掉
 5             clearTimeout(timeout);
 6             // 然后又创建一个新的 setTimeout, 这样就能保证interval 间隔内如果时间持续触发,就不会执行 fn 函数
 7             timeout = setTimeout(() => {
 8                 fn.apply(this, arguments);
 9             }, delay);
10         }
11     }
12     function click(a,b,c) {
13         console.log(this)
14         console.log(‘点击了‘,arguments);
15     }
16     var btn=document.querySelector(‘.btn‘);
17     btn.onclick=  debounce(click,2000)

 

节流:有点像定时漏斗,上面一直在加东西,下面的口是定时开关的,每隔几秒开一次,这样,当你滑动屏幕的时候,scroll事件是实时触发的,我们通过节流减少时间的触发次数,节约资源

 1     //节流throttle代码:
 2     function throttle(fn,delay) {
 3         let canRun = true; // 通过闭包保存一个标记
 4         return function () {
 5             // 在函数开头判断标记是否为true,不为true则return
 6             if (!canRun) return;
 7             // 立即设置为false
 8             canRun = false;
 9             // 将外部传入的函数的执行放在setTimeout中
10             setTimeout(() => {
11                 // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。
12                 // 当定时器没有执行的时候标记永远是false,在开头被return掉
13                 fn.apply(this, arguments);
14                 canRun = true;
15             }, delay);
16         };
17     }
18 
19     function sayHi(e) {
20         console.log(‘节流:‘, e.target.innerWidth, e.target.innerHeight);
21     }
22     window.addEventListener(‘resize‘, throttle(sayHi,500));

当然,上面的都是最简单的实现,更全面的写法可以通过lodash去引入

以上是关于防抖与节流区别以及使用场景的主要内容,如果未能解决你的问题,请参考以下文章

js防抖与节流

JavaScript性能优化8——防抖与节流

JavaScript性能优化8——防抖与节流

JavaScript防抖与节流函数:提高应用性能的利器

闭包与防抖节流

JavaScript防抖与节流