1

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?

Joudicek Jouda
  • 792
  • 2
  • 13
  • 30
  • Could you try this code? http://jsbin.com/bexerosaho/edit?js I created an array of strings, I used the index of the for to store the different strings, so all the array of strings is going to be in order – Rodrigo Juarez Apr 24 '16 at 22:00

2 Answers2

1

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

Rodrigo Juarez
  • 873
  • 1
  • 7
  • 17
  • This looks good, but I'm not sure if there isn't a mistake on my part. Will window.setTimeout() actually hold the loop and wait for the current delayed index to finish? With the whole problem with reindexing it looks like the setTimeout() holds the call of current index, but the loop continues meanwhile. I need to "pause" the loop to pause API calls. Do you think you can help with that? – Joudicek Jouda Apr 24 '16 at 22:19
  • Yes, no problem. Check this code http://jsbin.com/tugeqiqugo/edit?js I updated it using the forEach instead the traditional for loop, forEach creates a new scope for each iteration so it will keep the index. – Rodrigo Juarez Apr 24 '16 at 22:26
  • Please tell me if the answer provided worked for you and mark it as correct – Rodrigo Juarez Apr 24 '16 at 22:45
  • The ordering is fixed with this. But it doesn't solve the whole problem as I need to really PAUSE the API calls. See the edit in my question please. – Joudicek Jouda Apr 24 '16 at 23:24
  • Could you try something like this? http://jsbin.com/sobidetiqi/edit?js,output Now, after the API ends each call it will make the next request, if you want to delay that call, you just have to wrap the call to getData() around the setTimeout with the delay that you want. – Rodrigo Juarez Apr 25 '16 at 00:18
  • Yes! That's it! Can you please update your answer so I can accept it? – Joudicek Jouda Apr 25 '16 at 00:37
  • Ready! Updated the answer :) – Rodrigo Juarez Apr 25 '16 at 00:40
0

Try pushing results to an array including i within an object, when results .length is equal to value_array .length, sort stored array based on i, then set .val() of textareaElem

var time = 0, order = [];
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) {
        var curr = {index:i, value: result['val'] + '\n'};
        order.push(curr);
        if (order.length === value_array.length) {
          order.sort(function(a, b) {
             return a.index - b.index
          });
          textareaElem.val(order.join(""))
        }
      });
    }, time);
  })(textareaElem, value_array, i);
}
guest271314
  • 1
  • 15
  • 104
  • 177