什么事防抖和节流,有什么区别,如何实现

防抖和节流,本质上是优化高频率执行代码的一种手段,比如:resize、scroll、keypress、mousemove这些事件在触发的时候,会不断调用绑定在事件上的回调函数,这样极大浪费资源,降低前端性能。

为了优化体验,需要对这类事件进行调用次数的限制,所以我们采取了防抖和节流的手段来减少调用频率。

节流:在n秒内重复发生的事件,只有一次是生效的

防抖:在n秒后再执行该事件。

节流

完成节流可以使用时间戳与定时器的写法,使用时间戳的写法,事件会立即执行,停止触发后没有办法再次执行:

javascript 复制代码
function throttled1(fn, delay = 500) {
  let oldtime = Date.now()
  return function (...args) {
    let newtime = Date.now()
    if (newtime - oldtime >= delay) {
      fn.apply(null, args)
      oldtime = Date.now()
    }
  }
}

使用定时器的写法,delay毫秒后第一次执行:

javascript 复制代码
function throttled2(fn, delay = 500) {
  let timer = null
  return function (...args) {
    if (!timer) {
      timer = setTimeout(() => {
        fn.apply(this, args)
        timer = null
      }, delay);
    }
  }
}

两种写法的结合后:

javascript 复制代码
function throttled(fn, delay) {
  let timer = null
  let starttime = Date.now()
  return function () {
    let curTime = Date.now() // 
    let remaining = delay - (curTime - starttime) // 
    let context = this
    let args = arguments
    clearTimeout(timer)
    if (remaining <= 0) {
      fn.apply(context, args)
      starttime = Date.now()
    } else {
      timer = setTimeout(fn, remaining);
    }
  }
}

防抖

简单的封装:

javascript 复制代码
function debounce(func, wait) {
  let timeout;
  return function () {
    let context = this; // this
    let args = arguments; // event
    clearTimeout(timeout)
    timeout = setTimeout(function () {
      func.apply(context, args)
    }, wait);
  }
}

防抖和节流的相同点:

  • 都可以使用setTimeout实现
  • 目的都是降低回调函数的执行频率,节省计算资源

不同的是:

  • 函数防抖,在连续操作结束后,处理回调,利用clearTimeout和setTimeout实现;函数节流是在一段时间只执行一次,
  • 防抖关注的是一段时间内频繁触发的事件,只在最后执行一次;节流值关注的事一段时间内执行一次。

应用场景

防抖的使用场景有:

  • 搜索框输入,只需要用户最后一次输入完,再做处理
  • 手机号、邮箱验证输入检测
  • 窗口大小resize,只需窗口调整完成后,计算窗口的大小,防止重复渲染

节流的应用场景有:

  • 滚动加载,加载更多或者滚动到底部监听
  • 搜索框,搜索关联功能
相关推荐
一字白首1 分钟前
Vue Router 进阶,声明式 / 编程式导航 + 重定向 + 404 + 路由模式
前端·javascript·vue.js
d111111111d3 分钟前
C语言中static修斯局部变量,全局变量和函数时分别由什么特性
c语言·javascript·笔记·stm32·单片机·嵌入式硬件·学习
李瑞丰_liruifengv21 分钟前
使用 Claude Agent SDK 写一个 DeepResearch Agent
javascript·aigc·agent
江公望33 分钟前
VUE3 动态Prop 10分钟讲清楚
前端·javascript·vue.js
不会写DN33 分钟前
JavaScript call、apply、bind 方法解析
开发语言·前端·javascript·node.js
如果你好43 分钟前
理解 Proxy 原理及如何拦截 Map、Set 等集合方法调用实现自定义拦截和日志——含示例代码解析
javascript
czhc11400756631 小时前
c# winform1212
java·javascript·c#
一锤捌拾1 小时前
漫谈 JS 解析与作用域锁定
javascript
syt_10131 小时前
grid布局-子项放置3
前端·javascript·css
Gomiko1 小时前
JavaScript进阶(三):DOM事件
开发语言·javascript·ecmascript