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

JavaScript如何为pending状态的fetch请求设置超时跳过无响应节点

Fetch请求3秒超时自动跳过无响应节点实现方案

核心实现逻辑

原生fetch API没有内置超时中断机制,针对无响应请求挂起的问题,可通过两个原生能力组合解决:

  • 用AbortController生成请求中断信号,传入fetch配置项,支持主动终止未完成的请求
  • 用Promise.race()做超时竞速:同时发起fetch请求和超时倒计时,3秒内请求未返回就主动触发中断,直接跳过对应节点

完整可运行代码

// 节点列表
let nodes = [
  {
    "address": {
      "hostname": "192.168.1.1",
      "port": 31350
    }
  },
  {
    "address": {
      "hostname": "192.168.1.2",
      "port": 31350
    }
  }
]

/**
 * 拉取单个节点状态
 * @param {string} hostname 节点IP
 * @param {number} port 节点端口
 * @param {number} timeout 超时时间,默认3000ms
 * @returns 节点状态数据,失败返回null
 */
async function fetchNodes(hostname, port, timeout = 3000) {
  // 每个请求单独创建中断控制器,避免多请求互相干扰
  const controller = new AbortController();
  const signal = controller.signal;
  let timeoutId = null;

  try {
    const response = await Promise.race([
      fetch(`https://${hostname}:${port}/getstatus`, {
        method: 'post',
        // 原代码中body变量需提前定义,此处保留原有传参逻辑
        body: JSON.stringify(body),
        headers: { 'Content-Type': 'application/json' },
        signal: signal
      }),
      new Promise((_, reject) => {
        timeoutId = setTimeout(() => reject(new Error('请求超时无响应')), timeout);
      })
    ]);

    // 修复原代码漏写await的问题,否则会拿到pending状态的Promise
    const data = await response.json();
    console.log(`节点${hostname}:${port}数据拉取成功`, data);
    return data;
  } catch (err) {
    // 统一捕获超时、网络不通、接口报错等所有异常,直接跳过当前节点
    console.log(`节点${hostname}:${port}拉取失败,已跳过:${err.message}`);
    return null;
  } finally {
    // 清除定时器避免内存泄漏
    if (timeoutId) clearTimeout(timeoutId);
  }
}

// 批量发起节点请求
nodes.forEach(function(entry) {
  fetchNodes(entry.address.hostname, entry.address.port);
})

注意事项

  • 禁止多个请求共用同一个AbortController实例,否则单个请求超时会中断所有正在进行的请求
  • 如果需要等所有节点请求全部结束(无论成功失败)再执行后续逻辑,可将批量调用逻辑改为:
    const allResult = await Promise.allSettled(
      nodes.map(entry => fetchNodes(entry.address.hostname, entry.address.port))
    )
    // 后续统一处理allResult即可
    
  • AbortController为现代JS运行时原生API,Chrome 66+、Firefox 57+、Node.js 15+均默认支持,无需引入第三方依赖
  • 超时时间可通过fetchNodes的第三个参数自定义,默认值为3000毫秒即3秒

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 07:45:29