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

基于Promise实现Rest API冗余调用:优先返回首个200响应

实现方案

要实现你需求的逻辑,核心是优先竞速获取第一个200响应,同时兜底处理全失败的情况,结合AbortController还能主动终止不必要的请求,既优雅又高效。

最终实现代码

async function firstValidOrLastResponse(urls) {
  const abortController = new AbortController();
  const { signal } = abortController;
  let completedCount = 0;
  let lastFailedResponse = null;
  const totalRequests = urls.length;

  // 为每个请求绑定终止信号
  const fetchTasks = urls.map(url => fetch(url, { signal }));

  return new Promise((resolve) => {
    fetchTasks.forEach(task => {
      task.then(response => {
        completedCount++;
        // 找到第一个200响应,立即终止其他请求并返回结果
        if (response.ok) {
          abortController.abort();
          resolve(response);
        } else {
          lastFailedResponse = response;
          // 所有请求完成且无有效响应,返回最后一个失败结果
          if (completedCount === totalRequests) {
            resolve(lastFailedResponse);
          }
        }
      }).catch(error => {
        // 忽略主动终止请求的错误
        if (error.name === 'AbortError') return;
        
        completedCount++;
        lastFailedResponse = error;
        if (completedCount === totalRequests) {
          resolve(lastFailedResponse);
        }
      });
    });
  });
}

逻辑说明

  1. 竞速优先逻辑:

    • 给所有fetch请求绑定同一个AbortController信号,一旦某个请求返回200状态码,立即调用abort()终止其余未完成的请求,避免浪费网络资源。
    • 第一个符合条件的响应会直接作为最终结果返回,其余请求的后续回调不会干扰结果。
  2. 兜底处理逻辑:

    • 用completedCount统计已完成的请求数量,lastFailedResponse记录最后一个非200的响应(包括网络错误)。
    • 当所有请求都完成且没有找到200响应时,返回记录的最后一个失败结果。
  3. 垃圾回收优化:

    • 主动终止的请求会被浏览器取消,相关的请求资源会被自动回收;已完成但未被引用的响应,JS垃圾回收机制也会自动清理。

使用方式

直接传入需要请求的URL数组即可:

// 示例调用
const urls = ['https://api.example.com/1', 'https://api.example.com/2'];
firstValidOrLastResponse(urls)
  .then(result => {
    console.log('最终结果:', result);
  });

这种实现属于异步任务中的**"优先竞速+兜底回退"**模式,在需要从多个异步源获取结果、优先取符合条件的最快结果,否则取兜底结果的场景中非常实用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:35:27