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

循环内带setTimeout的Fetch请求仅返回最后一次迭代数据的问题

循环异步请求重复获取最后一次数据的问题解决

问题原因

  1. 循环里的i用var声明,属于全局变量,setTimeout是异步任务,会在整个循环结束后才执行,此时i已经变成14,current_date也完成了最后一次更新,导致所有请求都用了最后一个日期的值。
  2. 移除setTimeout后请求太密集,触发服务器限流机制(429错误),但此时部分请求能在current_date更新前执行,所以会看到非最后日期的数据。

解决方案

方案1:用let声明循环变量+复制日期+分散请求间隔

for(let i=0; i<14; i++){
    // 更新 current_date
    const currentDateCopy = current_date; // 保存当前迭代的日期,避免后续更新覆盖
    setTimeout(()=>{
        const date_url = 'url_and_params' + currentDateCopy + 'rest_of_url';
        fetch(date_url)
        .then(response => response.json())
        .then(data=>{
            console.log(data[0].stat1);
            data1.push(data[0].stat2);
        })
    }, i * 1000) // 每次请求间隔1秒,避免429限流
}
  • let i让每个循环迭代拥有独立的块级作用域,确保setTimeout回调能捕获当前迭代的i值。
  • 复制current_date到currentDateCopy,保证回调使用的是当前循环时的日期,而非最后一次更新的结果。
  • 调整延迟为i * 1000,让请求依次发送,避免触发服务器限流。

方案2:用闭包保存每次迭代的日期

for(var i=0; i<14; i++){
    // 更新 current_date
    (function(currentIterationDate){
        setTimeout(()=>{
            const date_url = 'url_and_params' + currentIterationDate + 'rest_of_url';
            fetch(date_url)
            .then(response => response.json())
            .then(data=>{
                console.log(data[0].stat1);
                data1.push(data[0].stat2);
            })
        }, i * 1000);
    })(current_date); // 将当前日期传入闭包,固定值
}
  • 用立即执行函数创建闭包,把当前迭代的current_date作为参数传入,确保每个setTimeout回调拿到的是对应迭代的日期值。
  • 同样通过i * 1000分散请求间隔,避免429错误。

方案3:用async/await串行请求(更易维护)

async function fetchAllData() {
    for(let i=0; i<14; i++){
        // 更新 current_date
        const date_url = 'url_and_params' + current_date + 'rest_of_url';
        try {
            const response = await fetch(date_url);
            const data = await response.json();
            console.log(data[0].stat1);
            data1.push(data[0].stat2);
        } catch (err) {
            console.error('请求出错:', err);
        }
        // 间隔1秒再发下一个请求
        await new Promise(resolve => setTimeout(resolve, 1000));
    }
}
fetchAllData();
  • 用async/await让请求按顺序执行,逻辑更直观,还能方便处理请求错误。
  • 每次请求后等待1秒,彻底避免请求过于频繁导致的429错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:21:49