如何在React(Vite项目)中对Fetch API实现每秒一次的限流?
解决ISS API请求限流与组件无限循环问题
核心方案:用定时器控制请求频率,配合useEffect清理机制
直接通过setInterval实现每秒一次的请求触发,同时在组件卸载时清理定时器,既避免依赖状态导致的无限循环,又能持续获取实时数据,还严格遵守API的每秒1次限流规则。
代码实现示例
import { useState, useEffect } from 'react'; function ISSLocation() { const [issData, setIssData] = useState(null); const [requestError, setRequestError] = useState(null); useEffect(() => { // 定义获取ISS数据的异步函数 const fetchIssPosition = async () => { try { const res = await fetch('https://wheretheiss.at/v1/satellites/25544'); if (!res.ok) { if (res.status === 429) { setRequestError('请求触发限流,已自动调整请求间隔'); // 触发限流后临时延长请求间隔至1.5秒 clearInterval(intervalId); intervalId = setInterval(fetchIssPosition, 1500); } else { throw new Error(`请求失败:${res.status}`); } } else { setRequestError(null); const data = await res.json(); setIssData(data); } } catch (err) { setRequestError(err.message); } }; // 启动每秒一次的请求定时器 let intervalId = setInterval(fetchIssPosition, 1000); // 组件卸载时清理定时器,防止内存泄漏 return () => clearInterval(intervalId); }, []); // 空依赖数组确保仅在组件挂载时初始化定时器 return ( <div className="iss-container"> <h3>国际空间站实时位置</h3> {requestError && <p className="error-text">{requestError}</p>} {issData && ( <div className="data-card"> <p>纬度:{issData.latitude.toFixed(4)}</p> <p>经度:{issData.longitude.toFixed(4)}</p> <p>飞行速度:{issData.velocity.toFixed(2)} km/h</p> <p>海拔高度:{issData.altitude.toFixed(1)} km</p> </div> )} </div> ); } export default ISSLocation;
关键细节说明
- 定时器控制频率:用
setInterval直接指定1000毫秒间隔发起请求,严格匹配API的每秒1次限流要求,彻底避免依赖状态导致的无限循环。 - 清理机制:useEffect的返回函数负责在组件卸载时清除定时器,防止内存泄漏。
- 限流错误处理:遇到429错误时,自动延长请求间隔,避免持续触发API限流,同时给用户反馈。
- 状态更新安全:仅在请求成功时更新
issData状态,不会因状态变更再次触发useEffect。
额外优化建议
- 可以添加加载状态,在请求未返回时显示加载提示;
- 如果API有分钟级限流,可以记录请求时间戳,确保在限流周期内不超出请求次数;
- 生产环境中可以给请求添加超时时间,避免请求挂起。
内容的提问来源于stack exchange,提问作者Alin-Alexandru Peter
相关产品推荐
相关产品推荐

