Home > Enterprise >  How to delay ajax using jquery
How to delay ajax using jquery

Time:12-05

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

CodePudding user response:

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

CodePudding user response:

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.

  • Related