You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React应用中降低Axios Get请求频率?解决409超限问题

请求第三方API触发409速率限制问题修复

问题说明

调用第三方API时因请求速度过快超出速率限制,返回409错误。目标是每5秒发起一次请求(API限制为每秒1次),但程序仍不间断请求。尝试用setInterval包裹请求函数设置4秒间隔,未解决问题。

错误截图:
409错误截图

当前代码:

import React, { useState, useEffect } from "react";
import ISS from "./ISS";
import axios from "axios";

function Map() {
    const [coordinates, setCoordinates] = useState('');
    const [loading, setLoading] = useState(true);
    
    useEffect(() => {
       setInterval(() => {
            getCoordinates();
        }, 4000)
    }, [])
    
    const getCoordinates =  async () => {
        try {
            const res = await axios.get("https://api.wheretheiss.at/v1/satellites/25544")
            setCoordinates(res.data);
            setLoading(false)
        } catch(err) {
            console.log(err);
        }
    }
    
    return(
        <div className="relative w-[620px] h-[475px] map flex content-center justify-center">
            {!loading && <ISS coordinates={coordinates} />}
        </div>
    );
}

export default Map;

问题根源

  1. 未清理定时器:useEffect中创建的setInterval没有在组件卸载时清除,若组件多次挂载,会生成多个定时器同时运行,请求频率翻倍触发速率限制。
  2. 请求可能重叠:setInterval会按时触发请求,不等待上一次异步请求完成,若请求耗时超过间隔时间,会出现多个请求并行,超出API限制。
  3. 函数引用不稳定:getCoordinates每次组件渲染都会重新创建,useEffect依赖数组为空,导致定时器捕获的是旧版本函数,可能引发预期外的重复调用。

修复方案

方案1:串行请求(推荐)

用setTimeout替代setInterval,确保上一次请求完成后再发起下一次,同时清理定时器避免内存泄漏。

import React, { useState, useEffect, useCallback } from "react";
import ISS from "./ISS";
import axios from "axios";

function Map() {
    const [coordinates, setCoordinates] = useState('');
    const [loading, setLoading] = useState(true);
    const [timerId, setTimerId] = useState(null);
    
    // 用useCallback稳定函数引用
    const getCoordinates = useCallback(async () => {
        try {
            const res = await axios.get("https://api.wheretheiss.at/v1/satellites/25544");
            setCoordinates(res.data);
            setLoading(false);
            // 请求完成后5秒发起下一次请求
            const id = setTimeout(getCoordinates, 5000);
            setTimerId(id);
        } catch(err) {
            console.log(err);
            // 出错后延迟5秒重试
            const id = setTimeout(getCoordinates, 5000);
            setTimerId(id);
        }
    }, []);
    
    useEffect(() => {
        // 初始化请求
        const id = setTimeout(getCoordinates, 0);
        setTimerId(id);
        
        // 组件卸载时清除定时器
        return () => {
            if (timerId) clearTimeout(timerId);
        };
    }, [getCoordinates, timerId]);
    
    return(
        <div className="relative w-[620px] h-[475px] map flex content-center justify-center">
            {!loading && <ISS coordinates={coordinates} />}
        </div>
    );
}

export default Map;

方案2:优化setInterval用法

若坚持使用setInterval,需添加定时器清理逻辑,并稳定函数引用:

import React, { useState, useEffect, useCallback } from "react";
import ISS from "./ISS";
import axios from "axios";

function Map() {
    const [coordinates, setCoordinates] = useState('');
    const [loading, setLoading] = useState(true);
    
    // 用useCallback稳定函数引用
    const getCoordinates = useCallback(async () => {
        try {
            const res = await axios.get("https://api.wheretheiss.at/v1/satellites/25544");
            setCoordinates(res.data);
            setLoading(false);
        } catch(err) {
            console.log(err);
        }
    }, []);
    
    useEffect(() => {
        // 创建定时器,每5秒执行一次
        const intervalId = setInterval(getCoordinates, 5000);
        // 组件卸载时清除定时器
        return () => clearInterval(intervalId);
    }, [getCoordinates]);
    
    return(
        <div className="relative w-[620px] h-[475px] map flex content-center justify-center">
            {!loading && <ISS coordinates={coordinates} />}
        </div>
    );
}

export default Map;

关键修复点

  • 清理定时器:组件卸载时清除定时器,避免无效请求和内存泄漏。
  • 稳定函数引用:用useCallback包裹请求函数,确保useEffect依赖正确,避免不必要的重新执行。
  • 串行请求控制:setTimeout方式保证请求按顺序执行,不会出现重叠,更适配API速率限制。

内容的提问来源于stack exchange,提问作者Philip Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:05:59