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

如何在XMLHttpRequest获取响应后循环调用请求(替代固定超时)

持续发起XMLHttpRequest(响应完成后自动重试)

针对你的需求——在每次请求拿到响应后立即发起下一次请求,同时避免严格短超时带来的问题,最合理的方式是把请求逻辑封装成函数,在请求完成(成功/失败/超时)的回调里递归调用这个函数。这种方式是串行执行的,每次只有一个请求在处理,不会给你的数据库和服务器造成额外的并发压力,完美适配数据库调用耗时不稳定的场景。

核心思路

不要用固定间隔的setInterval(它会不管上一次请求是否完成都发起新请求,容易导致请求堆积),而是让上一次请求的生命周期结束后,再触发下一次请求。这样既能保证持续轮询,又能避免并发请求的问题。

完整代码示例

function fetchData() {
  // 创建XHR对象(兼容旧IE)
  var request = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
  
  // 可选:设置一个较长的超时(比如10秒),避免请求无限挂起;如果完全不想超时,可以删掉这行
  request.timeout = 10000;

  // 请求成功完成时的处理
  request.onload = function() {
    if (this.status >= 200 && this.status < 400) {
      // 这里处理成功响应,比如解析数据
      try {
        const response = JSON.parse(this.responseText);
        console.log("Received data:", response);
      } catch (e) {
        console.error("Failed to parse response:", e);
      }
      
      // 响应处理完后,立即发起下一次请求
      // 如果想给服务器一点喘息时间,可以加个小延迟:setTimeout(fetchData, 1000);
      fetchData();
    } else {
      // 请求返回错误状态码(比如500、404),也选择重试
      console.error("Request failed with status:", this.status);
      // 错误情况可以延迟几秒再重试,避免频繁请求
      setTimeout(fetchData, 2000);
    }
  };

  // 网络错误时的处理(比如断网)
  request.onerror = function() {
    console.error("Network error occurred");
    // 网络错误建议延迟更久再重试
    setTimeout(fetchData, 3000);
  };

  // 请求超时的处理
  request.ontimeout = function() {
    console.warn("Request timed out, retrying...");
    // 超时后延迟5秒再重试,给服务器恢复时间
    setTimeout(fetchData, 5000);
  };

  // 配置请求(换成你的接口地址和请求方法)
  request.open("GET", "/your-api-endpoint", true);
  // 如果需要设置请求头,在这里加:request.setRequestHeader("Content-Type", "application/json");
  request.send();
}

// 启动第一次请求
fetchData();

为什么这种方式更适合你?

  • 无并发压力:每次只有一个请求在运行,不会因为数据库调用耗时久就同时发起多个请求,避免给数据库造成额外负载。
  • 灵活的重试策略:可以针对成功、失败、超时、网络错误等不同场景设置不同的重试逻辑(比如错误时延迟重试,成功时立即重试)。
  • 避免严格超时的问题:你可以把超时设置得足够长(比如10秒甚至更久),或者完全去掉超时,让请求一直等待服务器响应,直到完成。
  • 兼容旧环境:保留了对旧IE的ActiveXObject兼容,和你原来的代码逻辑一致。

对比固定间隔轮询的缺点

如果用setInterval(fetchData, 2000),当某次请求耗时超过2秒时,新的请求会在旧请求还没完成时发起,导致:

  • 多个请求同时访问数据库,增加负载
  • 响应返回顺序可能混乱(旧请求的响应可能比新请求晚回来)
  • 服务器可能因为并发请求过多触发限流

所以这种“响应完成后再发起下一次”的方式是更安全、更适合你场景的选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 10:06:09