0

I have this webpage, which when loaded runs a function (loadListItems) with some AJAX calls to populate a list with 10 items (there are multiple calls in a recursive matter, in order to get 10 VALID items).

There's a button on the page, which is visible at all times, and that button is there to load additional items in the list (the next 10 VALID items). The button calls loadListItems as well.

I want the button click to call the loadListItems function, however, if the previous call of the function is not finished, I want to queue the new call, so it runs whenever it finishes.

function pageLoad() {
   loadListItems();
}

var finished = false;
function loadListItems() {
   jQuery.ajax({
            url: ...
   }).done(function (data) {
      //do stuff with the data
      if (not enough data loaded) {
          //then call again recursively
          loadListItems();
      } else {
          //we're done
          var finished = true;
      }
    });
}

function buttonHandler() {
   if (finished) {
       loadListItems()
   } else {
       //run loadListItems whenever it finishes.
   }
}

How can achieve this?

Laureant
  • 979
  • 3
  • 18
  • 47
  • 4
    Why not to disable a button until your ajax returns data on an error? Also, your question might be duplicated: https://stackoverflow.com/questions/1822913/how-do-i-know-if-jquery-has-an-ajax-request-pending – Observer Oct 17 '18 at 14:59
  • So do you want to queue up a new call for each time the button is pushed, or just have one queued up at any point? – Paul Oct 17 '18 at 14:59
  • 3
    Add an array of functions then loop through them when finished (or execute immediately if already finished). Same as how jquery.document ready works. – freedomn-m Oct 17 '18 at 15:00
  • 4
    As an aside, flooding your server with 10 requests to get data isn't very efficient and may have some unwanted performance related side-effects. If possible, I'd strongly suggest you combine the data from all the requests and send only one, then deal with the response as an array, if necessary. – Rory McCrossan Oct 17 '18 at 15:01
  • The reason the code you have right now is not working is the line `var finished = true;`, which creates a new `finished` variable and sets it to true. You want `finished = true;` without the `var`, to set your global variable. – Heretic Monkey Oct 17 '18 at 15:41

1 Answers1

0

Like you said, make a queue and call it after finishing.

function pageLoad() {
   loadListItems();
}

var finished = false;
// you may just increase or decrease a number 
// but in case you need to call it with parameters, use array
var queue = [];

function loadListItems() {
   // you need to set finish flag to false whenever you start call
   finish = false;
   jQuery.ajax({
       url: ...
   }).done(function (data) {
      //do stuff with the data
      if (not enough data loaded) {
          //then call again recursively
          loadListItems();
      } else {
          // check queue
          if(queue.length > 0) {
              var params = queue.shift();
              // call with params or not
              loadListItems();
          } else {
              finished = true;
          }
      }
   });
}

function buttonHandler() {
   if (finished) {
       loadListItems()
   } else {
       //run loadListItems whenever it finishes.
       queue.push([parameters to retrieve data]);
   }
}

This is what you want. But please check comments for better advise. This is not the good solution.

wang
  • 1,660
  • 9
  • 20