JS问题:项目中如何区分使用防抖或节流?

前端功能问题系列文章,点击上方合集↑

序言

大家好,我是大澈!

本文约2300+字,整篇阅读大约需要6分钟。

本文主要内容分三部分,第一部分是需求分析,第二部分是实现步骤,第三部分是问题详解。

如果您只需要解决问题,请阅读第一、二部分即可。

如果您有更多时间,进一步学习问题相关知识点,请阅读至第三部分。

1. 需求分析

当用户多次频繁点击按钮时,只允许请求一次后端接口,避免重复无用请求。

没办法,谁让我们的客户就是会1秒点10次的超能力。

2. 实现步骤

2.1 选择防抖,还是节流?

对于控制事件触发的频率,我们应该很容易的就会想到JS中的防抖和节流。

防抖(Debounce)和节流(Throttle)是前端开发中最常用的优化处理方式,相信大家也都会使用。

但是如果谈起两者定义的区分,以及两者应用场景的不同,就会有朋友吐槽:"我靠,这不都一样嘛!"。

所以,我们到底要怎么选择呢?

2.2 两者定义的区分

简单的定义区分:

  • 防抖是一段时间内,多次执行变为只执行最后一次

  • 节流是一段时间内,多次执行变为只执行第一次

详细的定义区分:

  • 防抖(debounce)是指在一段时间内多次触发相同事件时,只执行最后一次触发的事件。

    这意味着,在一系列触发事件中,如果在指定的时间间隔内,发生了新的触发事件,那么前面的触发事件将被忽略,只有最后一次触发事件会被执行。

  • 节流(throttle)是指在一段时间内多次触发相同事件时,只执行一次事件。

    这意味着,无论触发事件发生多少次,在指定的时间间隔内只会执行第一次事件。

最后,再搭配上"大澈原创"之无敌美丽动人草图:

就问你,还有谁还区分不明白防抖和节流的定义,还有谁

2.3 两者应用场景的区分

真实的项目中,在不同的场景下灵活切换使用防抖或节流,才会更加减少不必要的资源消耗,更加提高前端应用的性能和响应性。

防抖(Debounce)的应用场景:

  • 搜索框输入:当用户在搜索框中输入内容时,可以使用防抖来延迟触发搜索请求。只有在用户停止输入一段时间后才会发送请求,避免频繁的请求发送。

  • 窗口调整:当窗口大小调整时,可以使用防抖来优化执行某些操作的频率,例如重新计算布局或重新渲染页面。

  • 按钮点击:当用户点击一个按钮时,可以使用防抖来确保只有在用户停止点击一段时间后才会执行相应的操作,避免误操作或重复执行。

节流(Throttle)的应用场景:

  • 页面滚动:当用户滚动页面时,可以使用节流来限制触发滚动事件的频率。例如,在滚动过程中只执行某些操作的固定时间间隔,以减少事件处理的次数。

  • 鼠标移动:当用户移动鼠标时,可以使用节流来控制触发鼠标移动事件的频率。例如,在一定时间内只执行一次鼠标移动的处理逻辑,避免过多的计算和渲染操作。

  • 实时通信:在实时通信应用中,如聊天应用或在线协作工具,可以使用节流来限制发送消息的频率,以避免发送过多的请求或数据。

2.4 两者的代码实例(了解即可别纠结)

防抖代码实例如下:

// 防抖:点击查询城市接口
var btn1 = document.querySelector("button");
var timer;

btn1.onclick = function () {
  //先清空延时器,然后再去调用接口
  clearTimeout(timer);
  // 每次点击按钮都会清空延时器,然后重新计时,延迟一秒执行函数
  timer = setTimeout(city, 3000);
};

function city() {
  ajax({
    method: "get",
    url: "https://geoapi.qweather.com/v2/city/lookup",
    data: {
      location: "青岛",
      key: "759cb11054344aaba4b8791ec40274dd",
    },
    aysn: true,
    contentType: "",
    success: function (res) {
      var obj = JSON.parse(res);
      console.log(obj, "请求成功的数据");
    },
  });

节流代码实例如下:

// 节流:鼠标移动在控制台打印坐标
//       fn(3000, handlePrint)
function fn(delay, behavior) {
  var timer = null;
  return function (val) {
    if (!timer) {
      timer = setTimeout(function () {
        //调用handlePrint函数
        behavior(val);
        timer = null;
      }, delay);
    }
  };
}

function handlePrint(val) {
  console.log(val, "我是鼠标坐标");
}

//调用fn把1000和handlePrint这个函数传进去
var handle = fn(3000, handlePrint);

document.addEventListener("mousemove", function (e) {
  handle(e.offsetX);
});

只是看看原理,差不多了解即可,不要太纠结,项目中肯定不会这么使用,不然会被喷的。

Vue等真实项目中,往往都会调用第三方库的函数,具体内容见第三部分。

3. 问题详解

3.1 常用的防抖节流函数库整理

流行的独立JavaScript 库:

  • Lodash (https://lodash.com/):Lodash 是一个功能强大的 JavaScript 实用工具库,提供了丰富的工具函数,包括 debounce 和 throttle。您可以使用 Lodash 中的 debounce 和 throttle 函数来实现相应的功能。

  • Underscore.js (https://underscorejs.org/):Underscore.js 是另一个流行的 JavaScript 实用工具库,类似于 Lodash,也提供了 debounce 和 throttle 函数,供您使用。

  • RxJS (https://rxjs.dev/):RxJS 是一个响应式编程库,它提供了丰富的操作符和工具函数,包括用于实现防抖和节流的操作符。您可以使用 RxJS 中的 debounceTime 和 throttleTime 操作符来实现相应的功能。

  • Async (https://caolan.github.io/async/):Async 是一个流程控制库,提供了多种异步操作的工具函数。它也包含了 debounce 和 throttle 函数的实现,供您使用。

  • Trottle-Debounce (https://github.com/niksy/throttle-debounce):Trottle-Debounce 是一个提供了防抖和节流函数的 JavaScript 库,它可以用于任何 JavaScript 应用程序,不依赖于特定的框架。

特定于框架的JavaScript 库:

  • VueUse (https://vueuse.org/):VueUse 是一个提供常用 Vue.js 自定义函数的库,其中包括了防抖和节流函数的实现。在 VueUse 中,您可以使用 useDebounce 和 useThrottle 这两个自定义函数来实现防抖和节流功能。

    import { useDebounce, useThrottle } from '@vueuse/core';

    // 防抖
    // 在值变化后延迟500毫秒触发
    const debouncedValue = useDebounce(value, 500);

    // 节流
    // 将函数封装为节流函数,每300毫秒触发一次
    const throttledFunction = useThrottle(myFunction, 300);

    // 在 Vue 组件中使用防抖和节流
    export default {
    setup() {
    const debouncedValue = useDebounce(value, 500);
    const throttledFunction = useThrottle(myFunction, 300);
    },
    }

  • React-use (https://github.com/streamich/react-use):React-use 是一个提供多种自定义 React hooks 的库,其中包括了 useDebounce 和 useThrottle。您可以使用 React-use 中的这些 hooks 在 React 组件中实现防抖和节流功能。

结语

建立这个平台的初衷:

  • 打造一个仅包含前端问题的问答平台,让大家高效搜索处理同样问题。

  • 通过不断积累问题,一起练习逻辑思维,并顺便学习相关的知识点。

  • 遇到难题,遇到有共鸣的问题,一起讨论,一起沉淀,一起成长。

感谢关注微信公众号:"程序员大澈",然后加入问答群,让我们一起解决实现所有BUG!

相关推荐
谢道韫6664 分钟前
今日总结 2024-12-27
开发语言·前端·javascript
嘤嘤怪呆呆狗14 分钟前
【插件】vscode Todo Tree 简介和使用方法
前端·ide·vue.js·vscode·编辑器
大今野20 分钟前
node.js和js
开发语言·javascript·node.js
ᥬ 小月亮27 分钟前
Js前端模块化规范及其产品
开发语言·前端·javascript
码小瑞42 分钟前
某些iphone手机录音获取流stream延迟问题 以及 录音一次第二次不录音问题
前端·javascript·vue.js
weixin_18944 分钟前
‌Vite和Webpack区别 及 优劣势
前端·webpack·vue·vite
半吊子伯爵1 小时前
开发过程优化·自定义鼠标右键菜单
前端·javascript·自定义鼠标右键菜单
xcLeigh1 小时前
HTML5实现好看的喜庆圣诞节网站源码
前端·html·html5
Tirzano1 小时前
vue3 ts 简单动态表单 和表格
前端·javascript·vue.js
杰~JIE1 小时前
前端工程化概述(初版)
前端·自动化·工程化·前端工程化·sop