什么是防抖和节流,以及如何编码实现。

本质上是优化高频率执行代码的一种手段
如:浏览器的 resizescrollkeypressmousemove 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能
为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用throttle(节流)和debounce(防抖)的方式来减少调用频率
一、定义:

  • 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
  • 防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时

二、一个经典的比喻:
想象每天上班大厦底下的电梯。把电梯完成一次运送,类比为一次函数的执行和响应
假设电梯有两种运行策略 debounce 和 throttle,超时设定为15秒,不考虑容量限制
电梯第一个人进来后,15秒后准时运送一次,这是节流
电梯第一个人进来后,等待15秒。如果过程中又有人进来,15秒等待重新计时,直到15秒后开始运送,这是防抖

三、js代码实现:

  节流

 1 function throttled(fn, delay = 500) {
 2     let timer = null
 3     let starttime = Date.now()
 4     return function () {
 5         let curTime = Date.now() // 当前时间
 6         let remaining = delay - (curTime - starttime)  // 从上一次到现在,还剩下多少多余时间
 7         let context = this
 8         let args = arguments
 9         clearTimeout(timer)
10         if (remaining <= 0) {
11             fn.apply(context, args)
12             starttime = Date.now()
13         } else {
14             timer = setTimeout(fn, remaining);
15         }
16     }
17 }

  防抖

function debounce(func, wait, immediate) {//immediate==true 立即执行
    let timeout;
    return function () {
        let context = this;
        let args = arguments;
        if (timeout) clearTimeout(timeout); // timeout 不为null
        if (immediate) {
            let callNow = !timeout; // 第一次会立即执行,以后只有事件执行后才会再次触发
            timeout = setTimeout(function () {
                timeout = null;
            }, wait)
            if (callNow) {
                func.apply(context, args)
            }
        }
        else {
            timeout = setTimeout(function () {
                func.apply(context, args)
            }, wait);
        }
    }
}

四、Vue使用npm的方式安装及使用:

  安装

 npm install throttle-debounce --save
 
使用
 
import { throttle, debounce } from 'throttle-debounce'
  参考文档 https://www.npmjs.com/package/throttle-debounce
 

 

posted @ 2022-09-08 14:51  Vition  阅读(109)  评论(0编辑  收藏  举报