微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在循环中处理lof Ajax请求并使用JavaScript防止“请求过多”

如何解决如何在循环中处理lof 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请求之后在循环日期。也许每个请求10秒,所以它不会说太多请求?所有核心代码都在成功功能中。我并不需要那么快,只是为了确保获得每月每个项目和每个天的所有信息。

我感谢您提供的任何帮助。

解决方法

我建议使用jQuery Deffered,因为您已经在使用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>

,

我认为这对后端是一个挑战-它的API应该支持通过一个请求执行此任务。 但是,如果您确定需要进行许多单独的请求,则只需使用并发限制(Live demo):

import CPromise from "c-promise2";
import $ from "jquery";

async function getDataFromWS(url,concurrency) {
  return CPromise.all(
    function* () {
      for (let i = 1; i < 32; i++) {
        const uriData = { date: "2020-08-0" + i };
        yield $.ajax({
          data: uriData,url,type: "GET",dataType: "json",async: true
        });
      }
    },{ concurrency }
  );
}

const buildCSVfile = async (responses) => {
  console.log(`Done: `,responses.map(JSON.stringify));
};

(async () => {
  const data = await getDataFromWS(
    `https://run.mocky.io/v3/753aa609-65ae-4109-8f83-9cfe365290f0?mocky-delay=1s`,10 // concurrent request limit 
  );
  await buildCSVfile(data);
})();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。