说说防抖和节流

防抖(debounce)的定义:触发高频函数事件后,n秒内函数只能执行一次,如果在n秒内这个事件再次被触发的话,那么会重新计算时间。(最后一个人说了算)

节流(throttle)的定义:高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率。(第一个人说了算)

个人理解防抖和节流的不同点和相同的地方:

区分:防抖动和节流本质是不一样的。防抖动是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行。

共同:这两兄弟的本质都是以闭包的形式存在,每次触发事件时都判断当前是否有等待执行的延时函数

鄙人用纸(方便)简单画一张幼儿园水平的图(并非无意贬低幼儿园小朋友),可能还没啥用:

上面说了那么多,感觉还是跟没说一样,举一些使用场景来加深理解吧。

防抖可用于:

1、search搜索联想,用户在不断输入值时,用防抖来节约请求资源。类似以前常使用lodash来解决搜索防抖的问题。

2、频繁操作点赞和取消点赞,因此需要获取最后一次操作结果并发送给服务器

节流可用于:

1、点击按钮,鼠标不断点击触发,mousedown(单位时间内只触发一次)

2、window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用节流来让其只触发一次

下面是实现代码

实现防抖:

 1 function debounce(fn) {
 2     let timeout = null; // 创建一个标记用来存放定时器的返回值
 3     return function () {
 4         clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
 5         timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
 6             fn.apply(this, arguments); // 修正 this 指向问题
 7         }, 500);
 8     };
 9 }
10 function sayHi() {
11     console.log('防抖成功');
12 }
13 let box = document.querySelector('body')
14 box.addEventListener('click', debounce(sayHi))

 

实现节流:

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

 

posted @ 2020-11-24 13:15  ZQ是水鱼  阅读(333)  评论(0编辑  收藏  举报