少小白学前端——JS篇(防抖与节流)

前言

       在开发过程中,我们往往会遇到一些问题,比如:提交表单,用户明明只点击了一次提交按钮,但却生成了两条数据,这时我们就会怀疑,用户会不会不小心多点了。
       当然也有可能是其他原因,但更多的,我们需要防止此类事件的发生,避免提交动作被频繁触发,尤其是在一些比较耗内存的操作上,更应如此。
       此时,大神会告诉我们,做一下防抖或节流,那么什么是防抖呢,节流又是什么呢,本文我们就来介绍一下。

一、概念

1、防抖(个人理解):防抖就是,一个事件如果被连续触发(间隔很短,小于设定的时间间隔n),那么它只有在时间间隔超过n时,执行一次(就是停止触发前的那一次,或者说最后一次),而且是在设定的时间间隔到达后执行,最常见的则是表单的校验。

例如:一个input输入框,在用户输入的时候,我们如果需要根据输入内容,做一些验证,那么在用户输入过程中,这个校验便会被不断触发,此时为了提高性能,提升用户体验,便可以使用防抖函数,在用户停止修改的n毫秒后,开始验证。

2、节流:节流是在一定时间内,如果一个函数被连续触发,那么它只执行第一次,超过了设定时间,才会再次执行。

例如:表单提交,我们可以让它一秒内只提交一次,不论这段时间内点击了几次。只有超过一秒后,才可以点击提交第二次。

二、如何实现防抖与节流

要想实现这两种策略,我们可以编写防抖函数和节流函数。

/**
*  防抖函数
*  @param fn:需要防抖的函数(也就是被频繁触发的函数)
*  @param delay:毫秒数(设定的时间间隔)
*/
function debounce(fn, delay) {
    let timer;
    return function(...args) {
      if (timer) {
        clearTimeout(timer)
      }
      timer = setTimeout(() => {
        fn.apply(this, args)
      }, delay)
    }
  }
  
/**
*  节流函数
*  @param fn:需要节流的函数(被连续触发的函数)
*  @param delay:毫秒数(设定的时间)
*/
  function throttle(fn, delay = 500) {
    let lastTime = 0;
    return function (...args) {
      const now = Date.now();
      if (now - lastTime >= delay) {
        fn.apply(this, args);
        lastTime = now;
      }
    }
  }

这两个函数,其实是利用了闭包的机制,保留了必要的状态信息,正确的管理函数的执行时机,让传进来的函数fn只执行一次。
(其中,apply函数是为了解决this指向问题的)

当然,如果不愿意写这两个函数,也可以使用lodash的.debounce()和.throttle()方法.

三、如何使用

react中,我们只需要将函数嵌套进去就可以了,完整代码如下:

import React from 'react';
import {Button} from "antd";

const Test = () => {
  // 防抖函数
  function debounce(fn, delay = 500) {
    let timer;
    return function(...args) {
      if (timer) {
        clearTimeout(timer)
      }
      timer = setTimeout(() => {
        fn(args)
      }, delay)
    }
  }

  // 节流函数
  function throttle(fn, delay = 500) {
    let lastTime = 0;
    return function (...args) {
      const now = Date.now();
      if (now - lastTime >= delay) {
        fn(args);
        lastTime = now;
      }
    }
  }

  // 执行函数
  const go = () => console.log('执行');

  return (
    <div>
      <Button onClick={debounce(go, 1000)}>防抖测试</Button>
      <Button onClick={throttle(go)}>节流测试</Button>
    </div>
  )
};

export default Test

上面呢,我给delay设置了默认值,这样传不传第二个参数就都可以了。

打开控制台,连续点击两个按钮,就可以看到,第一个按钮“防抖测试”,只有在停止点击且1000毫秒后,才会输出一次“执行”。
而第二个按钮,在连续点击的情况下,每500毫秒,输出一次。

当然,这是这两个函数在react中的使用,在vue中,尤其是vue3的组合式API中,写法有些许不同,直接上代码:

<template>
  <el-button type="primary" @click="handleDebounce">防抖测试</el-button>
  <el-button type="primary" @click="handleThrottle">节流测试</el-button>
</template>

<script setup>
// 防抖函数
function debounce(fn, delay = 500) {
  let timer;
  return function(...args) {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      fn(args)
    }, delay)
  }
}

// 节流函数
function throttle(fn, delay) {
  let lastTime = 0;
  return function (...args) {
    const now = Date.now();
    if (now - lastTime >= delay) {
      fn(args);
      lastTime = now;
    }
  }
}

// 要执行的函数
const go = () => console.log('执行');

const handleDebounce = debounce(go, 1000);
const handleThrottle = throttle(go, 1000);
</script>

这个和vue的事件绑定原理有关,普通js写法上应该是debounce(go, 1000)(),对于debounce需要再执行一次,而vue不支持这种方法,因此只能将其赋值给新的变量,然后在进行绑定。

四、应用场景

防抖:

  1. 输入框实时搜索:‌当用户在输入框中输入时,‌防抖技术可以延迟执行搜索查询,‌减少不必要的查询和服务器压力,‌避免频繁的网络请求。‌
  2. 窗口大小调整:‌当用户调整浏览器窗口大小时,‌使用防抖技术可以确保只在用户完成调整后再执行相应的响应逻辑,‌避免过多的布局计算。‌
  3. 表单验证:‌在用户停止输入一段时间后再执行验证,‌减少验证的次数,‌提升用户体验

节流:

  1. 页面滚动加载:‌在无限滚动的页面中,‌使用节流技术可以控制数据加载的频率,‌防止短时间内多次加载数据,‌提高页面加载性能。‌
  2. 按钮防重复点击:‌当用户点击按钮执行某个操作时,‌使用节流可以确保按钮在一定时间内只能触发一次,‌防止用户重复点击造成误操作。‌
  3. 鼠标移动事件和动画效果:‌在实现拖拽功能或基于时间的动画效果时,‌节流技术可以限制处理频率或动画帧率,‌降低计算开销。‌

好了,以上就是限制函数执行次数的两种策略——防抖和节流——的全部内容了。

  • 23
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值