13

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);
}
1
  • If there are two times as you mentioned, do you want 5 to print first and then 3 to print 3 seconds after that? Commented Aug 31, 2018 at 7:31

5 Answers 5

10

You can use IIFE (Immediately Invoked Function Expression) and function recursion instead. Like this:

let i = 0;
(function repeat(){
  if (++i > 5) return;
  setTimeout(function(){
    console.log("Iteration: " + i);
    repeat();
  }, 5000);
})();

Live fiddle here.

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

Comments

6

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);

Comments

6

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.

Comments

1

You can set time out period using i value dynamically. Like

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

function setDelay(i) {
  setTimeout(function(){
    console.log(i);
  }, i*1000);
}

Comments

0

You can think of something like that:

setDelay(1,5);

function setDelay(i, max) {
  setTimeout(function(){
    console.log(i);
    if(i < max){
      i++;
      setDelay(i, max);
    }
  }, 1000);
}

The idea is to set the next setTimeout(.. in a timeout. Of course you can modify it to have different long timeouts as well.

Hope i can help :)

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.