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

React调用多API触发429错误,求setTimeout正确使用方案

解决React中多API调用触发429 Too Many Requests错误的方案

调用多个API时,并发请求很容易触发服务端的频率限制,返回429错误。用setTimeout给每个请求设置递增的延迟,让请求错开时间发送,就能避免这个问题。以下是具体实现:

核心思路

通过setTimeout为每个API请求设置不同的延迟时间(比如逐个延迟1秒),确保请求不会同时发送,降低触发频率限制的概率。同时要注意清理定时器,避免React组件卸载后出现内存泄漏。

完整代码示例

import { useState, useEffect } from 'react';

const App = () => {
  const [dataList, setDataList] = useState([]);
  // 替换成你实际要调用的5个API地址
  const apiUrls = [
    'https://api.jikan.moe/v4/top/anime',
    'https://api.jikan.moe/v4/top/manga',
    'https://api.jikan.moe/v4/characters',
    'https://api.jikan.moe/v4/seasons/now',
    'https://api.jikan.moe/v4/recommendations/anime'
  ];

  // 单个API请求函数
  const fetchSingleApi = async (url, index) => {
    try {
      const response = await fetch(url);
      if (!response.ok) {
        if (response.status === 429) {
          console.error(`请求${url}触发频率限制,建议延长延迟时间`);
          return;
        }
        throw new Error(`请求失败:${response.status}`);
      }
      const result = await response.json();
      // 更新对应位置的数据
      setDataList(prev => {
        const newList = [...prev];
        newList[index] = result.data;
        return newList;
      });
    } catch (err) {
      console.error(`请求${url}出错:`, err);
    }
  };

  // 调度所有API请求,逐个添加延迟
  const loadAllData = () => {
    const timers = [];
    apiUrls.forEach((url, index) => {
      // 第1个请求立即发送,第2个延迟1秒,第3个延迟2秒...以此类推
      const timerId = setTimeout(() => {
        fetchSingleApi(url, index);
      }, index * 1000);
      timers.push(timerId);
    });
    return timers;
  };

  useEffect(() => {
    const timers = loadAllData();
    // 组件卸载时清理所有定时器,防止内存泄漏
    return () => {
      timers.forEach(timer => clearTimeout(timer));
    };
  }, []);

  return (
    <div>
      {dataList.map((data, index) => (
        <div key={index}>
          <h3>第{index+1}组数据</h3>
          {data ? (
            <ul>
              {data.slice(0, 5).map(item => (
                <li key={item.mal_id}>{item.title}</li>
              ))}
            </ul>
          ) : (
            <p>加载中...</p>
          )}
        </div>
      ))}
    </div>
  );
};

export default App;

关键细节说明

  • 延迟时间调整:如果还是触发429,就把index * 1000里的1000调大(比如改成1500或2000),延长每个请求的间隔时间。
  • 定时器清理:在useEffect的返回函数中用clearTimeout清理所有定时器,避免组件卸载后定时器仍在运行。
  • 错误处理:针对429错误做了专门提示,方便你快速调整延迟策略;其他请求错误也会打印日志,便于排查问题。

可选的串行请求方式

如果API限制非常严格,也可以用串行方式发送请求——前一个请求完成后,等待一段时间再发下一个。这种方式总耗时更长,但能确保请求完全错开:

const loadAllDataSerial = async () => {
  for (let i = 0; i < apiUrls.length; i++) {
    await fetchSingleApi(apiUrls[i], i);
    // 每个请求完成后等待1秒再发下一个
    await new Promise(resolve => setTimeout(resolve, 1000));
  }
};

// 在useEffect中调用:
useEffect(() => {
  loadAllDataSerial();
}, []);

内容的提问来源于stack exchange,提问作者Josh Lee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:05:16