跳到主要内容

防抖与节流

防抖

实现原理

防抖(Debounce)是指在一段连续操作结束后,只执行一次操作。

代码

函数式:

function debounce(fn: Function, delay: number): Function {
let timer: number | null = null;

return function (this: any, ...args: any[]) {
if (timer) {
clearTimeout(timer);
}

timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}

hooks:

import { useEffect } from 'react';

export function useDebounce(fn: Function, delay: number, deps: any[] = []) {
useEffect(() => {
const timer = setTimeout(() => {
fn();
}, delay);

return () => {
clearTimeout(timer);
};
}, deps);
}

使用场景

  • 输入框输入联想
  • 按钮提交防重复点击
  • 窗口大小变化,只触发一次 resize 事件
  • 搜索框输入,只触发一次请求

节流

实现原理

节流(Throttle)是指在一段连续操作中,每间隔一段时间执行一次操作。

代码

函数式:

function throttle(fn: Function, delay: number): Function {
let lastTime = 0;

return function (this: any, ...args: any[]) {
const now = Date.now();

if (now - lastTime >= delay) {
fn.apply(this, args);
lastTime = now;
}
};
}

hooks:

import { useEffect } from 'react';

export function useThrottle(fn: Function, delay: number, deps: any[] = []) {
useEffect(() => {
let lastTime = 0;

const timer = setInterval(() => {
const now = Date.now();

if (now - lastTime >= delay) {
fn();
lastTime = now;
}
}, delay);

return () => {
clearInterval(timer);
};
}, deps);
}

使用场景

  • 滚动事件,每隔一段时间触发一次
  • 鼠标移动,每隔一段时间触发一次
  • 窗口大小变化,每隔一段时间触发一次
  • 搜索框输入,每隔一段时间触发一次请求