axios 防抖与节流方案
在 Axios 中实现防抖(debounce)和节流(throttle)可以有效控制 API 请求频率,避免不必要的网络请求。以下是几种实现方案:
防抖(Debounce)方案
防抖是指在事件被触发后,延迟执行回调函数,如果在延迟时间内再次触发事件,则重新计时。使用 Lodash 的 debounce 方法
import axios from 'axios';
import { debounce } from 'lodash';
// 创建防抖的请求函数
const debouncedRequest = debounce(async (params) => {
try {
const response = await axios.get('/api/data', { params });
console.log(response.data);
} catch (error) {
console.error('请求失败:', error);
}
}, 500); // 500ms防抖间隔
// 调用示例
debouncedRequest({ q: 'search term' });
节流(Throttle)方案
节流是指在一定时间间隔内只执行一次回调函数,无论事件触发多少次。使用 Lodash 的 throttle 方法
import axios from 'axios';
import { throttle } from 'lodash';
// 创建节流的请求函数
const throttledRequest = throttle(async (params) => {
try {
const response = await axios.get('/api/data', { params });
console.log(response.data);
} catch (error) {
console.error('请求失败:', error);
}
}, 1000); // 1000ms节流间隔
// 调用示例
throttledRequest({ q: 'search term' });
ahooks 的 useRequest 防抖与节流实现
是的,ahooks 的 useRequest
内置了防抖(debounce)和节流(throttle)功能,通过插件机制实现。下面详细介绍其实现方式和使用方法。
防抖使用示例
import { useRequest } from 'ahooks';
import { getData } from '@/services/api';
function Demo() {
const { data, loading, run } = useRequest(getData, {
debounceWait: 500, // 防抖等待时间500ms
manual: true, // 手动触发
});
const handleSearch = (value: string) => {
run({ keyword: value }); // 输入变化时会自动防抖
};
return (
<div>
<input onChange={(e) => handleSearch(e.target.value)} />
{loading ? <div>加载中...</div> : <div>{data}</div>}
</div>
);
}
节流使用示例
import { useRequest } from 'ahooks';
import { getData } from '@/services/api';
function Demo() {
const { data, loading, run } = useRequest(getData, {
throttleWait: 1000, // 节流间隔1000ms
manual: true, // 手动触发
});
const handleClick = () => {
run(); // 频繁点击时会被节流控制
};
return (
<div>
<button onClick={handleClick}>点击获取数据</button>
{loading ? <div>加载中...</div> : <div>{data}</div>}
</div>
);
}
高级配置选项
防抖高级配置
useRequest(getData, {
debounceWait: 500,
debounceOptions: {
leading: true, // 延迟开始前调用
trailing: true, // 延迟结束后调用
maxWait: 1000, // 最大等待时间
},
manual: true,
});
节流高级配置
useRequest(getData, {
throttleWait: 1000,
throttleOptions: {
leading: true, // 节流开始前调用
trailing: true, // 节流结束后调用
},
manual: true,
});