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

如何在Promise.allSettled中实现API调用的间隔执行?

解决方案

原代码的问题在于一次性发起所有API请求,瞬间超过了每秒5次的调用限制,触发了服务端的限流机制,导致连接超时错误。要解决这个问题,需要严格控制请求频率,确保每200毫秒仅发起一次调用。

下面是修改后的串行请求实现,完全匹配每秒5次的限制:

async function getData(endpoints) {
  const results = [];
  for (const endpoint of endpoints) {
    try {
      const response = await fetch(`${urlStart}/${endpoint}/${urlEnd}`);
      const data = await response.json();
      results.push({
        status: 'fulfilled',
        value: { endpoint, data }
      });
    } catch (error) {
      results.push({
        status: 'rejected',
        reason: error
      });
    }
    // 最后一个请求无需等待
    if (endpoint !== endpoints[endpoints.length - 1]) {
      await new Promise(resolve => setTimeout(resolve, 200));
    }
  }
  return results;
}

代码说明:

  • 改用for循环串行处理每个请求,避免一次性发起所有调用
  • 每个请求完成后(无论成功或失败),等待200毫秒再处理下一个
  • 手动模拟Promise.allSettled的返回格式,确保和原代码输出结构一致,不影响后续逻辑

如果需要更高效率(比如同时保持最多5个并发请求),可以用批量间隔处理的方式:

async function getData(endpoints) {
  const results = [];
  const batchSize = 5;
  const interval = 1000; // 每1秒处理一批,刚好匹配每秒5次限制

  for (let i = 0; i < endpoints.length; i += batchSize) {
    const batch = endpoints.slice(i, i + batchSize);
    const batchResults = await Promise.allSettled(
      batch.map(async endpoint => {
        const response = await fetch(`${urlStart}/${endpoint}/${urlEnd}`);
        const data = await response.json();
        return { endpoint, data };
      })
    );
    results.push(...batchResults);
    // 非最后一批则等待1秒
    if (i + batchSize < endpoints.length) {
      await new Promise(resolve => setTimeout(resolve, interval));
    }
  }
  return results;
}

错误说明:

你遇到的连接超时错误(ConnectTimeoutError,错误码UND_ERR_CONNECT_TIMEOUT),本质是服务端检测到你超出调用频率限制后,拒绝了新的连接请求,最终导致客户端连接超时。通过控制请求发起频率,即可避免触发限流机制,解决该问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:36:20