You need to enable JavaScript to run this app. 如何使用Axios按顺序拉取远程对象数组关联数据解决429错误?
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Axios按顺序拉取远程对象数组关联数据解决429错误?

问题场景

持有一组Yelp商家的ID列表,希望通过Axios逐个拉取每个ID对应的商家关联数据。尝试编写如下逻辑实现拉取功能,但始终触发Axios返回的429(请求过多)错误,报错信息为:
[Unhandled promise rejection: Error: Request failed with status code 429]
已尝试过这段代码的多种改写形式,但问题始终存在,现有代码如下:

export const _fetchBusinessesDetails = async (ids : any[]) => {
  const businesses : Array<string> = [];
  const headers = {
    Authorization: 'Bearer <token>',
    'Content-Type': 'application/json',
  };
  ids.map(async (id : string) => {
    const res = await axios.get(`https://api.yelp.com/v3/businesses/${id}`, { headers });
    console.log(res.data || res.response.data.message);
    if (res.data) {
      businesses.push(res.data);
    } console.log(res.response.data.message);
  });
  return businesses;
};
问题根因
  • 核心错误是Array.map搭配async回调的写法完全达不到“逐个拉取”的效果:map遍历数组是同步执行的,会在毫秒级时间内触发所有async回调,相当于同一瞬间向Yelp接口发送所有ID对应的请求,瞬间打满接口限流阈值,必然返回429错误。
  • 缺少异步流程控制:外层的async函数不会等待map内部返回的Promise完成,会直接返回初始的空数组,根本拿不到拉取到的商家数据。
  • 缺少错误捕获逻辑:触发429错误时没有对应的catch块处理,异常直接抛出为未捕获的Promise rejection。
  • 代码存在逻辑bug:正常请求成功的流程中不存在res.response对象,直接读取该属性会触发空引用错误,中断执行流程。
修正实现

实现严格串行拉取、内置请求间隔与429自动重试的可运行代码:

export const _fetchBusinessesDetails = async (ids: string[]) => {
  const businesses: any[] = [];
  const headers = {
    Authorization: 'Bearer <token>',
    'Content-Type': 'application/json',
  };
  // 用for...of循环替代map,逐次等待上一个请求完成后再发送下一个
  for (const id of ids) {
    try {
      const res = await axios.get(`https://api.yelp.com/v3/businesses/${id}`, { headers });
      if (res.data) {
        businesses.push(res.data);
      }
      // 每次请求完成后留300ms间隔,匹配Yelp接口的限流要求
      await new Promise(resolve => setTimeout(resolve, 300));
    } catch (err: any) {
      // 捕获429限流错误,等待1秒后重试当前请求
      if (err.response?.status === 429) {
        await new Promise(resolve => setTimeout(resolve, 1000));
        const retryRes = await axios.get(`https://api.yelp.com/v3/businesses/${id}`, { headers });
        if (retryRes.data) businesses.push(retryRes.data);
        continue;
      }
      // 其他错误直接打印日志跳过,不中断整体拉取流程
      console.log(`拉取商家${id}失败:`, err.response?.data?.message || err.message);
    }
  }
  return businesses;
};
注意事项

Yelp公开接口的默认限流标准为每分钟最多500次请求,换算到每秒不到9次请求,瞬间并发发送大量请求一定会触发429错误。
不要直接用Promise.all批量提交所有请求,哪怕要做适度并发优化,也必须搭配请求间隔、限流控制和错误捕获逻辑,否则容易被接口封禁访问权限。

内容的提问来源于stack exchange,提问作者Ali H. Kudeir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.30 09:36:05