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

防抖和节流,本质上是优化高频率执行代码的一种手段,比如: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,只需窗口调整完成后,计算窗口的大小,防止重复渲染

节流的应用场景有:

  • 滚动加载,加载更多或者滚动到底部监听
  • 搜索框,搜索关联功能
相关推荐
yanlele2 小时前
AI Coding 时代下, 关于你会写代码这件事儿, 还重要吗?
前端·javascript·ai编程
打瞌睡的朱尤2 小时前
Vue day9 购物车,项目,vant组件库,vw,路由
前端·javascript·vue.js
cc.ChenLy6 小时前
【CSS进阶】毛玻璃效果与代码解析
前端·javascript·css
西门吹-禅6 小时前
node js 性能处理
开发语言·javascript·ecmascript
一只大侠的侠7 小时前
React Native for OpenHarmony:日期范围选择器实现
javascript·react native·react.js
EstherNi7 小时前
仿照elementui写图片放大的案例,但多加了下载按钮,vue3
javascript·vue.js·elementui
一只大侠的侠8 小时前
React Native for OpenHarmony:DatePicker 日期选择器组件详解
javascript·react native·react.js
JosieBook8 小时前
【Vue】15 Vue技术——Vue计算属性简写:提升代码简洁性的高效实践
前端·javascript·vue.js
x-cmd9 小时前
[x-cmd] Node.js 的关键一步:原生运行 TypeScript 正式进入 Stable
javascript·typescript·node.js·x-cmd
御坂10101号10 小时前
JIT 上的 JIT:Elysia JS 的优化实践与争议
开发语言·javascript·网络·性能优化·node.js·express