节流
让函数在指定时间内,最多只能执行一次;如果频繁触发,也只会按固定频率执行。
/**
* @param {Function} func - 需要节流的目标函数
* @param {number} wait - 节流时间间隔(毫秒),默认300ms
* @returns {Function} - 包装后的节流函数
*/
function throttle(func, wait = 300) {
// 保存上一次执行函数的时间戳
let lastExecuteTime = 0;
// 返回包装后的节流函数
return function (...args) {
// 保存当前上下文(比如DOM事件中的this)
const context = this;
// 获取当前时间戳
const now = Date.now();
// 核心逻辑:只有当前时间 - 上一次执行时间 >= 节流间隔,才执行函数
if (now - lastExecuteTime >= wait) {
// 执行原函数,传递上下文和参数
func.apply(context, args);
// 更新上一次执行时间为当前时间
lastExecuteTime = now;
}
// 未达到间隔:直接忽略,不做任何处理(无最后一次执行)
};
}import { useCallback, useRef } from 'react';
/**
* React 节流 Hook
* @param {Function} func - 需要节流的目标函数
* @param {number} wait - 节流时间间隔(毫秒),默认300ms
* @returns {[Function, Function]} - [包装后的节流函数, 重置节流的方法]
*/
function useThrottle(func, wait = 300) {
// 用 useRef 保存上一次执行时间(跨渲染周期保存,避免重置)
const lastExecuteTimeRef = useRef(0);
// 用 useRef 保存最新的函数引用(解决闭包陷阱)
const funcRef = useRef(func);
// 每次渲染更新函数引用,保证拿到最新的func
funcRef.current = func;
// 用 useCallback 缓存节流函数,避免组件重渲染时重新创建
const throttledFunc = useCallback((...args) => {
// 保存当前上下文
const context = this;
// 获取当前时间戳
const now = Date.now();
// 核心节流逻辑:达到间隔才执行
if (now - lastExecuteTimeRef.current >= wait) {
// 执行最新的业务函数
funcRef.current.apply(context, args);
// 更新上一次执行时间
lastExecuteTimeRef.current = now;
}
}, [wait]);
// 重置节流状态(可选:比如需要手动重置执行时间)
const resetThrottle = useCallback(() => {
lastExecuteTimeRef.current = 0;
}, []);
// 返回节流函数和重置方法
return [throttledFunc, resetThrottle];
}
export default useThrottle;.