手写防抖和节流

一、对防抖和节流的理解

防抖和节流是两种可以节省性能的编程技术,目的都是为了优化性能,能减少搜索引擎的损耗,防止出现页面堵塞卡顿现象,提高用户体验。

什么是防抖(Debounce)

一段时间内,事件在我们规定的间隔 n 秒内多次执行,回调只会执行一次。

防抖函数的作用是控制函数在一定时间内的执行次数。简单点说就是通过防抖函数让某个触发事件在 n 秒内只会被执行一次

什么是节流(Throttle)

一段时间内,事件在每次到达我们规定的间隔 n 秒时触发一次。

节流函数的作用是在一个单位时间内最多只能触发一次函数执行,如果这个单位时间内多次触发函数,只能有一次生效。

二、防抖函数的应用场景

  1. 输入框实时搜索:当用户需要在搜索框内进行实时搜索,使用防抖函数可以延迟搜索请求的发送,只在用户停止输入一段时间后才真正发起请求,避免频繁的请求操作。
  2. 表单输入验证:在表单输入过程中,每次用户输入都可能触发验证操作。使用房否函数可以延迟搜索请求的发送,只在用户输入完毕一段时间后进行验证,避免频繁的验证操作。

三、节流函数的应用场景

  1. 页面滚动事件:当用户滚动页面时,会频繁触发滚动事件。使用节流函数可以控制滚动事件的触发频率,避免过多的计算和渲染操作,提高页面的性能和流畅度。
  2. 频繁点击按钮提交:在某些场景下,点击按钮可能会触发重复的提交操作。使用节流函数可以限制按钮点击的触发频率,防止重复的提交

四、实现手写防抖和节流函数

防抖函数

  <div class="box">
    <input type="text" id="demo">
  </div>
  
  <script>
   function req(value){
    console.warn("request: " + value + ", time: " + new Date());
  }
  const inputBox = document.getElementById("demo");
  inputBox.addEventListener("keyup",e=>{
    // req(e.target.value); //未进行防抖处理,
    debounce(()=>req(e.target.value),500) //进行了防抖处理
  })

  // 防抖函数
    /**
   * @desc 防抖函数:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
   * @param {Function} func 函数
   * @param {Number} wait 延迟执行毫秒数
   * @param {Boolean} immediate true 表示立即执行,false 表示非立即执行
   */
  let timeout
  function debounce(func, wait = 500, immediate = false) {
    // 清除定时器
    if (timeout) clearTimeout(timeout)
    // 立即执行,此类情况一般用不到
    if (immediate) {
      let callNow = !timeout
      timeout = setTimeout(() => {
        timeout = null
      }, wait)
      if (callNow) typeof func === 'function' && func()
    } else {
      // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
      timeout = setTimeout(() => {
        typeof func === 'function' && func()
      }, wait)
    }
  }
  </script>

节流函数

  <button id="demo" style="margin: 50px;">点击按钮</button></button>
  <script>
      let value = 1
      function req(){
          console.warn("request: " + value++ + ", time: " + new Date());
      }
      const ele = document.getElementById("demo");
      ele.addEventListener("click", (e) => {
        // req();//未使用节流函数
        throttle(() => req(), 2000) //使用了节流函数,2秒内执行一次
      });

      /**
     * @desc 节流函数:在一定时间内,只能触发一次
     * @param {Function} func 函数
     * @param {Number} wait 延迟执行毫秒数
     */
      let previous = 0
      function throttle(func, wait = 500) {
        let now = Date.now()
        if (now - previous > wait) {
          typeof func === 'function' && func()
          previous = now
        }
      }

  </script>

五、总结

两种方式根据不同的场景选择使用,都能达到节省性能的效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值