skip to Main Content

I’m trying to save some information from a web service, it is a lot of data and I have to make a lot of Ajax requests, after many requests so quick, the server justs throws "Too many requests" which makes sense…

My code looks something like this:

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);
}

I need all this code to be synchronous, I assume that I need to use something like setTimeout or so because I tried it but then the buildCSVfile() function executes before the loops, I guess the delay should be after each ajax request in the date for loop. Maybe 10 seconds per request so it won’t say too many requests? All the core code is in the success function. I don’t need this to be fast, just to make sure to get all the info, per item and per day of the month.

I appreciate any help given.

2

Answers


  1. I suggest using jQuery Deffered since you already use jQuery.

    Read up on jQuery Deferred to understand the inner workings.
    It basically implements a system based on Promises.

    Your code could end up something like:

    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>
    Login or Signup to reply.
  2. I believe this is a challenge for backend- its API should support doing this task by one request.
    But if you’re sure that you need to make many separate requests, just use concurrency limit (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);
    })();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search