首页 > 解决方案 > 如何处理循环中的大量 Ajax 请求并使用 JavaScript 防止“请求过多”

问题描述

我正在尝试从 Web 服务中保存一些信息,这是很多数据,我必须发出很多 Ajax 请求,在这么快的许多请求之后,服务器只是抛出“请求太多”,这是有道理的.. .

我的代码看起来像这样:

function getDataFromWS()
{
    define some vars
    $ make an ajax request to MY database to get every item i will request on the external WS 
    (that query returns like 150 items to arrayFromResponse)
    
    //Loop into the array with 150 items
    arrayFromResponse.forEach((element)=>{
        //For loop to make request for each day of the month e.g. August 31 days
        for(let i = 1; i <= 31; i++){
            //change uri to match each day using i
            uriData.date = '2020-08-0'+i;

             //This is where after many requests it throws error 429 "Too many"
                $.ajax({
                    data: uriData,
                    url: uri,
                    type: 'GET',
                    async: false,
                    success : function(response){
                        
                            //Save data from response to some arrays I use
                    
                    },
                    error: function(response){
                        console.log(response);
                        console.log('Error');
                    }
                });
        } 
    })
    //After all that looping and requests make a CSV file
    buildCSVfile(dataFromResponses);
}

我需要所有这些代码都是同步的,我假设我需要使用 setTimeout 之类的东西,因为我试过了,但是 buildCSVfile() 函数在循环之前执行,我猜延迟应该在日期中的每个 ajax 请求之后for 循环。每个请求可能需要 10 秒,所以它不会说太多请求?所有核心代码都在success函数中。我不需要这个很快,只是为了确保获得所有信息,每个项目和每个月的每一天。

我感谢提供的任何帮助。

标签: javascriptjqueryajaxxmlhttprequest

解决方案


我建议使用 jQuery Defered,因为您已经使用 jQuery。

阅读 jQuery Deferred以了解内部工作原理。它基本上实现了一个基于 Promises 的系统。

您的代码最终可能类似于:

function getDataFromWS()
{
  var deferred = new $.Deferred();
  var dataFromResponses = [];
  //   define some vars
  //   $ make an ajax request to MY database to get every item i will request on the external WS 
  //   (that query returns like 150 items to arrayFromResponse)

  var uri = "https://jsonplaceholder.typicode.com/todos/";
  var arrayFromResponse = ["SOME DATA"];
  //Loop into the array with 150 items
  arrayFromResponse.forEach((element)=>{
    //For loop to make request for each day of the month e.g. August 31 days
    for(let i = 1; i <= 10; i++){
      var uriData = {};
      //change uri to match each day using i
      uriData.date = '2020-08-0'+i;

      var def = new $.Deferred();
      //This is where after many requests it throws error 429 "Too many"
      $.ajax({
        data: uriData,
        cache: false,
        url: uri + i,
        type: 'GET',
        async: false,
        success : function(response){
          console.log("Got data at day " + i);
          dataFromResponses.push(response);
        },
        error: function(response){
          deferred.reject(response);
          console.log('Error');
        }
      });
    }
  });
  //After all that looping and requests make a CSV file
  deferred.resolve(dataFromResponses);
  return deferred.promise();
}

// and call it with:

$.when(getDataFromWS()).done(function(dataFromResponses){
  console.log(dataFromResponses);
  // buildCSVfile(dataFromResponses);
}).fail(function(response){
  console.error(response);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>


推荐阅读