js中,防抖、节流的原理和区别

在前端开发的过程中,会有很多场景会频繁触发事件,比如说搜索框实时发请求,onmousemove, resize, onscroll等等,但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数。,咋办呢?这时候就应该用到函数防抖和函数节流了!

为什么要防抖

有的操作是高频触发的,但是其实触发一次就好了,比如我们短时间内多次缩放页面,不应该每次缩放都去执行操作,应该只做一次就好。再比如说监听输入框的输入,不应该每次都触发监听,应该是用户完成一段驶入后再进行触发
防抖就是防止抖动,避免事件的重复触发

思路:事件触发后开启一个定时器,如果事件在这个定时器限定的时间内再次触发,则清除定时器,再写一个定时器,定时器时间到则触发

举个栗子 复制代码
 // 1.声明定时器变量
    // 2.每次鼠标移动的时候要先判断是否有定时器  如果有先清除以前的定时器
    // 3.如果没有定时器  执行定时器  存储变量
    // 4.定时器里写函数
    const obox = document.querySelector('div')
    let i = 1;
    function mousemove() {
      obox.innerHTML = i++;
    }
    function debounce(fun, time) {
      let timer
      return function () {
        let that = this;
        if (timer) clearTimeout(timer)
        timer = setTimeout(function () {
          fun.call(that)
        }, time)
      }
    }
    obox.addEventListener('mousemove', debounce(mousemove, 1000))

为什么要节流

防抖存在一个问题,事件会一直等到用户完成操作后一段时间再操作,如果一直操作,会一直不触发。比如说是一个按钮,点击就发送请求,如果一直点,那么请求就会一直发布出去。这里正确的思路应该是第一次点击就发送,然后上一个请求回来后,才能再发
节流就是减少流量,将频繁触发的事件减少,并每隔一段一段时间执行。即控制事件触发的频率

两种节流实现方式

  • 使用定时器实现
javascript 复制代码
function fn(fun,t){
      let timer = null;
      return function(){
        let that = this;
        if(!timer){
          timer = setTimeout(function(){
            fun.call(that)
            timer = null
          },t)
        }
      }
    }
    obox.addEventListener('mousemove',fn(mousemove,1000))

上面代码中,触发事件后,会直接重新赋值timer为一个定时器,到时间后执行事件处理程序,重新赋值timer为null。在这期间,因为timer的值是一个定时器,if判断是不会执行的,必须重新赋值为null后才会重新执行

  • 时间戳实现
kotlin 复制代码
 function fn(fun, time) {
      let start = 0;
      return function () {
        let that = this;
        let current = Date.now()
        if (current - start >= time) {
          fun.call(that)
          start = current
        }
      }
    }
    obox.addEventListener('mousemove', fn(mousemove, 1000))

上面代码中,触发事件后,定义开始触发事件的时间为start为零,获取当前的时间戳赋值给current,判断当前时间与初始时间是否超过间隔,如果超过了就把当前这个时间戳赋值给start,然后执行事件处理程序。(因为初始时间为零,所以第一次触发会直接执行)

总结

  • 防抖和节流相同点:

防抖和节流都是为了阻止操作高频触发,从而浪费性能。

防抖和节流区别:

防抖是触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。适用于可以多次触发但触发只生效最后一次的场景。
节流是高频事件触发,但在n秒内只会执行一次,如果n秒内触发多次函数,只有一次生效,节流会稀释函数的执行频率。

今天的知识就分享到这里啦。欢迎大家在评论里指点讨论

学到知识了就点个赞叭

相关推荐
Ai-_Man11 小时前
我需要批量导出Poe左边栏所有对话,而不是一条具体的对话内容,你们AI导出鸭可以吗?
开发语言·前端·javascript·人工智能·小程序
u01110267512 小时前
Vue 页面离开后还在轮询?统一清理计时器、监听器与观察器
前端·javascript·vue.js
大猩猩X12 小时前
vue 表格组件 vxe-table 实现多行编辑,支持增删改查与校验
前端·javascript·vue.js·vxe-table
冒险的豆子14 小时前
Proxy & Vue 响应式(合并精简版,适合面试)
前端·javascript·vue.js
Java后端的Ai之路14 小时前
前端技术Vue-18-视图中的渲染
前端·javascript·vue.js
zttbee21 小时前
echarts图表tooltip色块失效
前端·javascript·echarts
虚无境1 天前
如何用AI帮我写出实用的插件
前端·javascript·ai编程
zimoyin1 天前
在 C# 里嵌入 JavaScript:用 Jint 做可热更新的自动化脚本(从入门到踩坑)
javascript·c#·自动化
FRing031 天前
JavaScript入门到精通二十六(变量提升、函数剩余参数、展开运算符、ES6箭头函数)
开发语言·前端·javascript·es6·箭头函数
OpsEye1 天前
怎么实现大模型的按用户、按应用配额限流?
javascript·ai编程