前端请求防抖

对于表单提交等场景,用户手滑可能会出现连续点击多次提交按钮的情况,此时前端需要做下请求防抖。

实现思路:定义一个防抖列表,在请求拦截中进行判断,如果这个接口中有携带我们定义需要处理防抖的参数,则进行防抖逻辑。如果只是单纯的切换查询条件,没必要也不能做防抖处理,否则会影响用户体验。

防抖逻辑大致为:

  1. 根据请求时已有的参数,如接口地址、请求类型、接口参数等等,自行将其拼成字符串
  2. 然后判断这个字符串在不在这个防抖列表中
  3. 如果在那就请求拦截,如果不在,则将这个字符串添加至这个防抖列表中
  4. 同时设置一个定时器,500毫秒后删除这个字符串

这里以vue3+axios为例

import axios, { AxiosInstance, AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'

const config = {
  baseURL: '/api',
  timeout: 5000
}

const store = useGlobalToken()

class RequestHttp {
  service: AxiosInstance
  debouncUrlList: string[]
  public constructor(config: AxiosRequestConfig) {    
    ...
    this.debouncUrlList = [] // 防抖的url列表
    // 请求拦截
    this.service.interceptors.request.use(
      async (config: AxiosRequestConfig | any) => {
        // 防抖处理
        if (config.restrict) this.debounce(config)
        ...
    )

    // 响应拦截
    this.service.interceptors.response.use()
  }

  // 防抖处理
  debounce(config: AxiosRequestConfig) {
    const data = config.method === 'get' ? config.params : config.data
    const str = (((config.method as string) + config.url) as string) + JSON.stringify(data)
    if (~this.debouncUrlList.indexOf(str)) {
      ElMessage.warning('请勿重复请求')
      throw new Error('重复请求')
    }
    this.debouncUrlList.push(str)
    setTimeout(() => {
      this.debouncUrlList = this.debouncUrlList.filter((e) => e !== str)
    }, 500)
  }

  // 清除防抖
  clearDebounce(config: AxiosRequestConfig) {
    const data = config.method === 'get' ? config.params : config.data
    const str = (((config.method as string) + config.url) as string) + JSON.stringify(data)
    this.debouncUrlList = this.debouncUrlList.filter((e) => e !== str)
  }
}
export default new RequestHttp(config)

clearDebounce方法为手动清除防抖,在特定的场景下自行调用即可

使用:

在定义api的文件中,在需要防抖的接口上添加restrict: true参数即可

// 新增
export const postMarketTrack = (params: any) => {
  return http.post('xxx', params, { restrict: true })
}

### 前端 input 实现防抖与节流的方法及区别 在前端开发中,`input` 事件的频繁触发可能会导致性能问题。为了优化性能,可以使用防抖和节流技术来限制回调函数的执行频率。 #### 防抖(Debounce)实现方法 防抖的核心思想是:在事件被触发 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。以下是基于 `setTimeout` 的防抖实现方法: ```javascript function debounce(func, delay) { let timer; return function(...args) { const context = this; clearTimeout(timer); timer = setTimeout(() => { func.apply(context, args); }, delay); }; } // 示例:将防抖应用到 input 事件 const searchInput = document.getElementById('search-input'); searchInput.addEventListener('input', debounce(function() { console.log('输入内容:', this.value); fetchSuggestions(this.value); // 模拟发送请求 }, 500)); // 在用户停止输入 500 毫秒后触发回调 ``` 这种实现方式确保了只有当用户停止输入一段时间后才会触发回调函数[^1]。 #### 节流(Throttle)实现方法 节流的核心思想是:规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行。以下是基于 `setTimeout` 的节流实现方法: ```javascript function throttle(func, limit) { let inThrottle; return function(...args) { const context = this; if (!inThrottle) { inThrottle = true; setTimeout(() => { func.apply(context, args); inThrottle = false; }, limit); } }; } // 示例:将节流应用到 input 事件 const searchInput = document.getElementById('search-input'); searchInput.addEventListener('input', throttle(function() { console.log('输入内容:', this.value); fetchSuggestions(this.value); // 模拟发送请求 }, 500)); // 每隔 500 毫秒最多触发一次回调 ``` 这种实现方式确保了在指定的时间间隔内只执行一次回调函数[^1]。 #### 防抖与节流的区别 虽然防抖和节流的核心目标相似——限制频繁事件对系统性能的影响,但它们在具体的实现方式、适用场景以及对用户体验的影响上存在显著区别。 - **防抖**:适用于需要等待用户操作完全结束后再执行的场景,例如搜索框的自动补全功能。它通过延迟执行回调函数来减少不必要的计算。 - **节流**:适用于需要在一定时间内均匀分布事件处理的场景,例如滚动事件或窗口调整事件。它通过限制回调函数的执行频率来优化性能[^2]。 #### Vue 或 React 中的实现 在 Vue 或 React 中,可以通过自定义钩子或工具函数来实现防抖和节流。以下是一个在 React 中的示例: ```javascript import { useState, useCallback } from 'react'; function useDebounce(callback, delay) { const timer = useRef(); return useCallback((...args) => { clearTimeout(timer.current); timer.current = setTimeout(() => callback.apply(this, args), delay); }, [callback, delay]); } function SearchInput() { const [value, setValue] = useState(''); const debouncedFetch = useDebounce(fetchSuggestions, 500); const handleChange = (e) => { setValue(e.target.value); debouncedFetch(e.target.value); }; return <input type="text" value={value} onChange={handleChange} />; } ``` #### 注意事项 - 在选择防抖或节流时,需根据具体需求权衡性能和用户体验。 - 对于实时性要求较高的场景,如表单验证,可能需要结合两者的优势来设计解决方案[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值