2

I'm trying to iterate over a string array with a delay of a few milliseconds every step of iteration. Something like below -

var l = ['a', 'b', 'c'];
var delay = 5000;
for(var i = 0;i < l.lenght;i++) {
    document.querySelectorAll("a[title='" + l[i] + "']")[0].parentNode.children[0].click();
    delay = 5000 + Math.floor(Math.random() * 5000) + 1;
   **<WAIT for 'delay' number of milliseconds**
}

I've been able to convert the code to below using setTimeout() method -

var i = 0;
var interval = setInterval(function() {
    if (i < l.length) {
        document.querySelectorAll("a[title='" + l[i] + "']")[0].parentNode.children[0].click();
       i++;
   }
   else {
      clearInterval(interval);
   }
   //delay = 5000 + Math.floor(Math.random() * 5000) + 1); **NOT SURE where to change the delay variable**
}, delay);

But the delay variable essentially becomes a constant once setTimeout kicks off. How to change the delay variable in each iteration?

4 Answers 4

2

You can make a recursive timer function for this:

Try the following :

function displayValue(){
  
  let arr = ['a', 'b', 'c'];
  let delay = 1000;  
  let i = 0;
  
  function timerFunction(i){
     if(i === arr.length)
      return;
      setTimeout(()=>{
        console.log(arr[i]);
        i++;
        timerFunction(i);
      }, delay);
      delay = delay + 1000 + Math.floor(Math.random() * 4000);
  } 
  
  timerFunction(i);
}

displayValue();

Sign up to request clarification or add additional context in comments.

Comments

1

Could you try replacing that delay variable with a function such as this?

var i = 0;
var interval = setInterval(
function() {
  if (i < l.length) {
    document.querySelectorAll("a[title='" + l[i] + "']")[0].parentNode.children[0].click();
    i++;
  }
  else {
    clearInterval(interval);
  }
},
function() {
  return 5000 + Math.floor(Math.random() * 5000) + 1;
}
);

1 Comment

Thank you. Will it change the delay in every iteration though? If so, this is probably the simplest solution. I'll give it a try.
1

setInterval, which you have used in your example, initializes a callback launching every (circa) N ms, where N is fixed. You have to clear it later on with clearInterval.

setTimeout on the other hand means - invoke my callback after ~N time. You could then call another setTimeout inside the callback, with a different N.

as an example:

function callback() {
  /* 
    your logic here
  */
  delay = 5000 + Math.floor(Math.random() * 5000) + 1);
  setTimeout(callback, delay); // for your "clearInterval" case - just don't invoke this
}

setTimeout(callback, initialDelay);

1 Comment

Thanks for the explanation. Yes, I mentioned setTimeout() in my example by mistake, now I see that my initial approach using setInterval() would never have worked.
0

This thread appears the closest I found to the fundamental question of how to iterate through an array at a random time interval, which isn't as easy as one would think. Although arguably a little general for the specific question asked, the currently accepted answer looks the closest match to the fundamental question. The code below is a minor modification which looks to provide a random delay on the first pass and logs each random delay after the logging each array value.

function displayValue(){

    let arr = ['a', 'b', 'c','d', 'e'];
      let delay = Math.floor(Math.random()*10000);  
      let i = 0;
      
      function timerFunction(i){
         if(i === arr.length)
          return;
          setTimeout(()=>{
            console.log(arr[i]);
            console.log(`delay was ${Math.floor(delay/1000)} seconds`);
            i++;
            timerFunction(i);
          }, delay);
          delay = Math.floor(Math.random()*10000);
      } 
      
      timerFunction(i);
    }
    
    displayValue();

The value of the above modification probably depends on the context.

Interestingly, applying the introduction to forEach from bootcamp provides an alternate solution which is probably closer related to the OP!

var colors = ["red", "green", "blue", "yellow"];

function printArr(x){
    var random = Math.round(Math.random()*60000);
    setTimeout(() => {
        console.log(x);
        console.log(`Delay was ${Math.floor(random/1000)} seconds`)
    }, random);
};
colors.forEach(printArr);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.