Home > Software engineering >  How do I parse an array with delay and modify it while it is being looped through?
How do I parse an array with delay and modify it while it is being looped through?

Time:01-15

I'm needing a function that can loop through an array while accounting for delay, and not adding the delay all at once while going through an array.

My example of what I need:

const array = [ 0.06, 0.08, 0.04, 0.05, 0.06, 0.03 ];

loop(array); // this is the function

userInputForStop(); // my function where something causes the array to be deleted/set to []

I've tried:

const array = [ ""var array = [ "this", "is", "not", "going", "to", "work" ];
for (var i = 0; i < array.length; i  ) {
  (function (i) {
    setTimeout(function () {
      if(i == "going") array = [];
      console.log(array[i])
    }, 1000 * i);
  })(i);
};

And this method will not work as the for loop has already gone through each item and set the timeout already. Therefore when the item matches "going", it wouldn't stop whatever is coming afterwards.

I've seen many other posts about arrays with delay although they all seem to parse all the items in an array and multiplying the delay by the counter(this is not what I want).

I'm wanting a looping function that would allow me to fully stop any looping of values after a certain item. (but also have delay between each value)

CodePudding user response:

We could try to recreate some sort of sleep function in JavaScript with promises. Then we can use that sleep function in loops, since loops respect await:

const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const array = ["this", "is", "definitely", "going", "to", "work"];

(async () => {
  for (const item of array) {
      if (item === "going") array.length = 0;

      console.log(item);

      await delay(100);
  }
})();

and if you write an async generator that uses this sleep function, we could simplify the core loop a little with for-await loops:

const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const array = ["this", "is", "definitely", "going", "to", "work"];

async function* delayedIterator(array, ms) {
    for (const item of array) {
        yield item;
        
        await delay(ms);
    }
}

(async () => {
    for await (const item of delayedIterator(array, 100)) {
        if (item === "going") array.length = 0;
        
        console.log(item);
    }
})();

CodePudding user response:

It's kind of hard to understand what your use case is (this would help hugely) but you could just clear down the future timers:

const timers = []
const array = [ ""var array = [ "this", "is", "not", "going", "to", "work" ];
for (var i = 0; i < array.length; i  ) {
  (function (i) {
    timers.push(setTimeout(function () {
      if(array[i] == "going") {
         for (var j = i   1; i < timers.length; j  ) {
             clearTimeout(timers[j])
         }
         array = [];
         
      }
      console.log(array[i])
    }, 1000 * i));
  })(i);
};]
  • Related