Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 4 setTimeout() with variable delay and wait

I have a list of events with timestamp. What I want is to display the events based on the timestamp:

To add a delay:

delay = timestamp(t+1) - timstamp(t)

I know this doesn't work well with setTimeout, but there is an workaround, if the timeout is constant, in my case is not.

Is it possible to make the next setTimeout() wait for the previous one? To be specific, if the first setTimeout() has a 5 second delay and the second one has 3 seconds, the second one will appear first. I want them to be in the same order but execute one after the other.

This example works for a constant delay, but I want to calculate the delay based on the information I take iterating the list.

for (i = 1; i <= 5; ++i) {
  setDelay(i);
}

function setDelay(i) {
  setTimeout(function(){
    console.log(i);
  }, 1000);
}
like image 815
Cristina Avatar asked Aug 31 '18 07:08

Cristina


2 Answers

When using the latest Typescript or ES code, we can use aync/await for this.

let timestampDiffs = [3, 2, 4];

(async () => {
  for (let item of timestampDiffs) {
    await timeout(item * 1000);
    console.log('waited: ' + item);
  }
})();

function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

We need to wrap the for loop in an async immediately invoked function because to support await.

We also do need a timeout function that returns a promise once the timeout is complete.

After that, we wait for the timeout to complete before continuing with the loop.

like image 139
nipuna777 Avatar answered Oct 07 '22 03:10

nipuna777


Don't call it within a loop, as it won't wait for the setTimeout to complete.

You can instead pass a list of times that you want to wait, and iterate them recursively:

let waits = [5000, 3000, 1000];

function setDelay(times) {
  if (times.length > 0) {
    // Remove the first time from the array
    let wait = times.shift();
    console.log("Waiting", wait);
    
    // Wait for the given amount of time
    setTimeout(() => {
        console.log("Waited ", wait);
        // Call the setDelay function again with the remaining times
        setDelay(times);
    }, wait);
  }
}

setDelay(waits);
like image 35
user184994 Avatar answered Oct 07 '22 01:10

user184994