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

递归实现Web请求Promise竞态超时重试的逻辑异常排查

Web请求超时竞态重试问题排查

问题场景

开发过程中遇到Web请求响应耗时波动较大的问题:部分请求0.1秒即可完成响应,部分请求耗时长达20秒。

初始设计思路

  • 为请求配置固定超时阈值,超时触发后立即发起新的请求
  • 保留所有之前未完成的pending状态请求,让所有在途请求共同参与竞态
  • 任意一个请求成功完成后,立即终止整个竞态流程,终止其余未完成请求的处理逻辑
  • 同时欢迎针对该场景提供更优的替代实现方案

当前实现代码

const timeoutLimit = 300;
const timeoutMessage = 'Response timed out';

/** Executes a request, retrying on timeouts, until it returns successfully. */
export default async function requestWithTimeout(request, count) {
  const timeout = new Promise((resolve, reject) => {
    setTimeout(() => reject(timeoutMessage), timeoutLimit);
  });

  const apiCall = new Promise((resolve, reject) => {
    request
      .catch((err) => reject(err))
      .then((resp) => resolve(resp));
  });

  count += 1;

  const result = await Promise.race([apiCall, timeout])
    .catch((err) => {
      console.log(err, count);
      return (err === timeoutMessage) ? Promise.race([apiCall, requestWithTimeout(request, count)]) : err;
    })
    .then((val) => {
      console.log('returned', count);
      return val;
    });

  console.log(count, result);

  return result;
}

运行异常表现

当前代码运行后,控制台始终输出如下顺序的日志,所有请求按递归嵌套顺序依次返回,无法在首个请求完成时立即终止竞态流程:

Response timed out 1
Response timed out 2
returned 1
returned 2
returned 3
data 1
data 2
data 3

预期的正确日志输出顺序如下(首个请求成功后立刻结束整体流程,其余已发起请求按实际完成顺序打印日志即可):

Response timed out 1
Response timed out 2
returned 1
data 1
returned 3
data 3
returned 2
data 2

待解决问题

排查现有代码无法实现预期竞态效果的根因,给出可运行的修正方案,也可提供更优的替代实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:27:17