Search code examples
javascriptjqueryajaxdelay

Keep output order while waiting between AJAX API calls


I have a jQuery script that calls a web API to get a JSON formatted output. The API is designed for a small number of consecutive calls. I need to get a larger amount of data from the API, but I don't want to send the inputs manually a few by few because that would take ages.

I don't care how long it takes for the script to run as long as it wouldn't be needed for someone to do something manually. So I added some delay. The problem is the result is now not in the order I send it to the API so I can't connect the output with input.

How can I keep the order of lines in textareaElem to line up with input?

var time = 0;
for (var i = 0; i < value_array.length; i++) {
  if (i > 0 && i % 5 == 0) {
    time = Math.floor((Math.random() * 45) + 15) * 1000; // Random waiting
  } else {
    time = 0;
  }

  (function (textareaElem, value_array, i) {
    window.setTimeout(function() {
      $.getJSON("myscript.php?var="+encodeURIComponent(value_array[i]), function(result) {
        textareaElem.val(textareaElem.val() + (result['val'] + '\n');
      });
    }, time);
  })(textareaElem, value_array, i);
}

EDIT: There is an error in my code. I need the script to PAUSE the API calls for some time. The code above only delays the processing of some rows WHILE it is processing other rows. This is because setTimeout() is asynchronous.

This also introduces the problem with order. The ordering can be solved with @Rodrigo Juarez answer, but it won't help with the whole problem because I need to PAUSE the API calls every few calls.

How can I make the PAUSE?


Solution

  • This is the solution that I found, just create and array, you already have the indexes of each request, so you only have to assign the value in the array to each result, then use the method join

     var time = 0;
    var text = [];
    var index = 0;
    
    //function to be called to retrieve the data
    var getData = function (index) {
          $.getJSON("myscript.php?var="+encodeURIComponent(value_array[index]), function(result) { 
            text[index] = result.val + '\n';
            textareaElem.val(text.join(""));
            if (index < value_array.length){
              getData(index++);
            }
        });
    };
    
    //Just calling the function with index 0
    if (value_array.length) {
      getData(0);
    }
    

    Link to the code