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

如何实现带可变间隔的递归setTimeout资源批量请求?

实现按间隔批量请求资源的递归setTimeout方案

给定配置

let config = {
  "requests": [
    {
      "resource": "foo",
      "interval": 1000
    },
    {
      "resource": "bar",
      "interval": 500
    },
    {
      "resource": "baz",
      "interval": 3000
    },
    {
      "resource": "qux",
      "interval": 500
    },
    {
      "resource": "zot",
      "interval": 500
    },
  ],
  // 其他配置...
}

需求说明

需要实现递归的setTimeout调用,按以下逻辑批量请求资源:

  • 累计500ms时,请求['bar', 'qux', 'zot'];
  • 累计1000ms时,请求['bar', 'qux', 'zot', 'foo'];
  • 累计1500ms时,再次请求['bar', 'qux', 'zot'];
  • 累计3000ms时,请求['bar', 'qux', 'zot', 'foo', 'baz'];
  • 以此循环,适配任意未知的间隔配置及资源数量。

初步思路代码

const { requests } = config
let intervals = new Set()
for (let obj of requests) {
  intervals.add(obj.interval)
}
intervals = Array.from(intervals).sort((a, b) => a - b) // [500, 1000, 3000]

let currentRequest

const makeRequest = resources => {
  // 携带resources数组向服务器发送请求
  // 再次调用initRequest初始化下一次请求
}

const initRequest = () => {
  const interval = 500 // 仅示例,实际间隔需动态计算
  const resources = [] // 需在此确定本次请求的资源列表
  setTimeout(() => {
    makeRequest(resources)
  }, interval)
}

initRequest()

可行实现方案

核心逻辑是动态计算下一个触发时间点,并筛选出该时间点需要请求的资源,然后递归调度下一次请求:

const { requests } = config;

// 记录累计运行时间,初始为0
let totalTime = 0;

// 模拟发送请求的函数,可替换为实际请求逻辑
const makeRequest = (resources, triggerTime) => {
  console.log(`累计${triggerTime}ms,请求资源:`, resources);
  // 实际场景中这里写axios/fetch等请求代码
};

// 计算下一个触发时间点
const getNextTriggerTime = () => {
  let nextTime = Infinity;
  // 遍历所有不同的间隔值,找到大于当前totalTime的最小倍数
  const uniqueIntervals = [...new Set(requests.map(item => item.interval))];
  for (const interval of uniqueIntervals) {
    // 计算当前间隔的下一个倍数
    const nextMultiple = Math.ceil(totalTime / interval) * interval;
    if (nextMultiple < nextTime) {
      nextTime = nextMultiple;
    }
  }
  return nextTime;
};

// 筛选当前触发时间点需要请求的资源
const getResourcesToRequest = (triggerTime) => {
  return requests
    .filter(item => triggerTime % item.interval === 0)
    .map(item => item.resource);
};

// 递归调度请求的核心函数
const scheduleNextRequest = () => {
  const nextTriggerTime = getNextTriggerTime();
  const delay = nextTriggerTime - totalTime;

  setTimeout(() => {
    // 更新累计时间
    totalTime = nextTriggerTime;
    // 获取本次需要请求的资源
    const resources = getResourcesToRequest(totalTime);
    // 发送请求
    makeRequest(resources, totalTime);
    // 递归调度下一次请求
    scheduleNextRequest();
  }, delay);
};

// 启动调度
scheduleNextRequest();

逻辑说明

  1. 累计时间跟踪:用totalTime变量记录从启动到当前的累计毫秒数,每次触发请求后更新为当前触发时间点。
  2. 下一个触发时间计算:遍历所有唯一的间隔值,计算每个间隔的下一个大于当前totalTime的倍数,取其中最小的那个作为下一次触发时间。
  3. 资源筛选:在触发时间点,筛选出所有间隔能整除该时间点的资源(即该时间点是资源间隔的整数倍),组成请求列表。
  4. 递归调度:每次请求发送完成后,立即递归调用调度函数,确保循环执行。

这个方案完全适配未知的间隔配置,不管有多少种间隔值,都能自动计算正确的触发时间和请求资源列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 16:05:34