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

Node.js中如何在列表尚有元素时重复执行API调用函数

解决方案:处理API频率限制并循环直到列表为空

先明确核心优化方向:放弃遍历1到10000的低效逻辑,直接处理目标ID列表;同时解决API频率限制问题,成功获取数据后移除对应ID,直到列表清空。

修改后的完整代码

let my_list = [1, 7, 9, 112, 15, 17, 19, 25]; // 你的初始ID列表

// 封装带重试机制的请求函数,处理429频率限制
const fetchBreweryWithRetry = async (id) => {
  try {
    const brewery = await findBreweriesById(id);
    return brewery;
  } catch (error) {
    // 针对429错误做重试处理
    if (error.response?.status === 429) {
      // 优先用API返回的重试等待时间,默认60秒
      const retryAfter = parseInt(error.response.headers.get('Retry-After')) || 60;
      console.log(`触发频率限制,等待${retryAfter}秒后重试ID ${id}`);
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      // 递归重试当前ID
      return fetchBreweryWithRetry(id);
    }
    // 其他错误直接抛出,也可根据需求自定义处理
    throw error;
  }
};

const processList = async () => {
  // 循环直到ID列表为空
  while (my_list.length > 0) {
    // 复制当前列表的副本,避免遍历中修改原列表导致的遍历异常
    const currentIds = [...my_list];
    for (const id of currentIds) {
      // 主动控制请求频率:每分钟100次,即每600ms发起一次请求
      await new Promise(resolve => setTimeout(resolve, 600));
      
      try {
        const brewery = await fetchBreweryWithRetry(id);
        if (brewery) {
          console.log(brewery.brewery_name);
          // 成功获取数据后,从原列表移除该ID
          const index = my_list.indexOf(id);
          if (index !== -1) {
            my_list.splice(index, 1);
          }
        } else {
          console.log(`ID ${id} 未找到对应brewery`);
          // 如果不需要保留未找到结果的ID,可在这里同样执行移除操作
          // const index = my_list.indexOf(id);
          // if (index !== -1) my_list.splice(index, 1);
        }
      } catch (error) {
        console.log(`处理ID ${id} 时出错:`, error.message);
      }
    }
  }
  console.log("所有元素处理完成!");
};

// 启动处理流程
processList();

关键逻辑说明

  1. 频率控制与重试

    • 主动设置600ms间隔(对应每分钟100次请求),从根源减少触发429的概率
    • 封装fetchBreweryWithRetry函数,遇到429错误时,根据API返回的Retry-After头等待后自动重试,避免程序中断
  2. 循环与列表修改

    • 用while (my_list.length > 0)作为循环条件,确保直到所有ID处理完成才停止
    • 每次循环开始时复制当前列表到currentIds,避免遍历过程中修改原列表导致的元素跳过问题
  3. 元素移除时机

    • 在成功获取到brewery数据后,立即用splice从my_list中移除对应ID,保证下一轮循环不会重复处理已完成的ID

额外优化建议

如果ID数量较多,推荐用Set代替数组存储ID,提升查找和移除的效率:

let my_ids = new Set([1, 7, 9, 112, 15, 17, 19, 25]);
// 判断存在:my_ids.has(id)
// 移除元素:my_ids.delete(id)

内容的提问来源于stack exchange,提问作者Tendekai Muchenje

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 05:05:16