skip to Main Content

I need to access an API but I dont want to shoot with 100 requests at the same time so I want to make 1 request per second so I write:

$.each(added_collections, function(index, collection) {
      $.each(collection, function(index1, page) {
        $.each(page, function(index2, product) {
          
               setTimeout(function() {
            
             $.ajax({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            },
            type: "POST",
            url: '/get_data',
            dataType: "json",
            data: meta_data,
            success: function(data) {
              
                console.log(data);
                
                
           },
           error: function(data){
            console.log(data);
           }
         });

          }, 1000);
           
        });
        });
    });

but this code do not make 1second between requests

enter image description here

How I can make 1 ajax call per second

2

Answers


  1. I’m not sure what data you need to be in that ajax call, but here’s a way to throttle in the manner you’re after. Build the array of indexes (products) first. Then use a separate helper function to call the ajax and call itself again recursively when complete.

    let allThings = [];
    
    $.each(added_collections, function(index, collection) {
      $.each(collection, function(index1, page) {
        $.each(page, function(index2, product) {
          allThings.push(product)
        });
      });
    });
    
    doAjax(0)
    
    const doAjax = index => {
      if (allThings.length >= index) return console.log("DONE");
      setTimeout(() => {
        $.ajax({
          headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
          },
          type: "POST",
          url: '/get_data',
          dataType: "json",
          data: meta_data,
          success: function(data) {
            console.log(data);
            doAjax(++index);
          },
          error: function(data) {
            console.log(data);
          }
        });
      }, 1000)
    }
    
    Login or Signup to reply.
  2. Ideally you want to use a throttle function of some kind. You can use a library for this, or can write a simple one which may work for your use case like this (this technique can be used for other functions as well)

    function throttle(fn, interval) {
      // keep track of the last time the function was called
      let lastCalled = 0;
    
      // return a throttled version of the function
      return function throttledFunction(...args) {
        // get the current time
        const now = Date.now();
    
        // if the function has been called within the interval, wait until the interval has elapsed
        if (now - lastCalled < interval) {
          setTimeout(() => throttledFunction(...args), interval - (now - lastCalled));
          return;
        }
    
        // update the last time the function was called
        lastCalled = now;
    
        // call the function with the given arguments
        return fn(...args);
      }
    }
    

    Then to use it with your Ajax method, something like this

    function makeRequest() {
      $.ajax({
            headers: {
              'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            },
            type: "POST",
            url: '/get_data',
            dataType: "json",
            data: meta_data,
            success: function(data) {
              console.log(data);
           },
           error: function(data){
            console.log(data);
           }
         });
    }
    
    const makeThrottledRequest = throttle(makeRequest, 1000);
    
    $.each(added_collections, function(index, collection) {
      $.each(collection, function(index1, page) {
        $.each(page, function(index2, product) {
          makeThrottledRequest();
        });
      });
    });
    

    The reason the calls all happen at about the same time in your code is all the timeouts begin at about the same time. Ie between each iteration of the loop, basically no time passes, so the timers all end 1 second later.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search