js防抖和节流的实现原理及应用场景

概念
函数防抖(debounce):触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。

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

函数节流(throttle)与 函数防抖(debounce)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象

1、函数防抖(debounce)

  • 实现方式:每次触发事件时设置一个延迟调用方法,并且取消之前的延时调用方法
  • 缺点:如果事件在规定的时间间隔内被不断的触发,则调用方法会被不断的延迟

1)应用场景:

  1. scroll事件滚动
  2. 浏览器窗口的缩放resize事件
  3. 搜索框输入查询的时候
  4. 表单验证
  5. 按钮的提交事件

2)代码

 1 function debounce (fn, delay = 1000) {
 2   let time = null
 3   return function () {
 4     // 获取当前this
 5     let that = this
 6     // 判断是否已经存在,如果存在直接清除
 7     if (time) {
 8       clearTimeout(time)
 9     }
10     time = setTimeout(() => {
11       // 使fn 中this,执行当前调用者,并传入参数
12       fn.apply(that, arguments)
13     }, delay)
14   }
15 }

1,函数节流(throttle)

  • 实现方式:每次触发事件时,如果当前有等待执行的延时函数,则直接return

1)应用场景:

  1. DOM元素拖拽功能实现
  2. 计算鼠标移动距离
  3. 监听scroll滚动事件请求数据
  4. 搜索、提交等按钮功能

2)代码

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

 

posted @ 2022-12-19 17:05  程序员肉包子  阅读(388)  评论(0编辑  收藏  举报