0

I have the following code but it doesn't seem to work. I want to log to the console "dark-green", have it wait a couple milliseconds, then log "light-green", all WITHOUT using setInterval or setTimeout. Is this possible with javascript?

function logGreen() {
 console.log("dark-green");
 wait(200);
 console.log("light-green");
}

function wait(ms) {
  var time = new Date();
  var milliseconds = time.getMilliseconds();
  var startTime = milliseconds;
  var currentTime = milliseconds;
  while(currentTime - startTime < ms) {
 currentTime = milliseconds;
 }
}

The problem I am running into is that the the loop breaks the browser so to speak, and I'm not sure how to fix this. Is there a way to do this with a for loop?

Michael Mungai
  • 33
  • 1
  • 2
  • 6

2 Answers2

1

The issue with your code is that the value of currentTime is not being updated properly in your while loop.

The code inside your while loop will execute indefinitely (infinite loop) causing a stack overflow - I'm assuming that's what you mean by "breaks the browser". This is because your condition is always true:startTime and currentTime are the same value (currentTime - startTime < 200)

Try this instead:

 while(currentTime - startTime < ms) {
   time = new Date();
   currentTime = time.getTime();
 }

Creating a new Date object and calling time.getTime() inside the loop will return the latest time and should fix your problem. Use getTime() instead of getMilliseconds() because the latter only returns a number between 0 and 999 (ie. less than a second). This limited upper range will be problematic for your code because getMilliseconds() will only return the number of milliseconds elapsed since the previous second.

Justin Chan
  • 308
  • 2
  • 9
  • I think you correctly diagnosed the problem, but no: calling `getMilliseconds()` does not return the latest time. – Bergi Dec 19 '17 at 01:22
  • @Bergi Corrected. – Justin Chan Dec 19 '17 at 01:57
  • Also the OP must not use `getMilliseconds` but rather `getTime`, or this will fail horrible if the waiting period crosses a second boundary. – Bergi Dec 19 '17 at 02:00
  • 1
    @Bergi I'm learning as much as OP here. Yes, use `getTime` because `getMilliseconds` only returns a number between 0 and 999. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMilliseconds – Justin Chan Dec 19 '17 at 02:12
  • OP here. Thank you so much, this worked. I am running into a new issue where I want to apply the same logic but instead of logging "dark-green" and "light-green" to the console, i would like to change the background color of a div. I've reposted the question here: and was wondering if anyone had some input as to how I could achieve this. – Michael Mungai Dec 19 '17 at 17:32
  • https://stackoverflow.com/questions/47892293/change-div-background-color-for-one-second-then-return-it-to-the-original-color – Michael Mungai Dec 19 '17 at 17:32
  • If that solved your problem please click the big checkbox to accept the answer! – Justin Chan Dec 19 '17 at 17:57
0

You can you generator as lazy evaluating. Please see below example. To run an infinite loop setInterval. You can modify the code according to your use.

This is supported on es6 supported browser and node 8.9.1LTS or above.

function* asyncRandomNumbers() {
  let tm = new Date().getTime();
  while (true) {
    let updatedTm = new Date().getTime()
    if(updatedTm - tm >= 1000){
      tm = updatedTm;
      yield tm;
    }
  }
}
for (var val of asyncRandomNumbers()) {
  console.log(val) // outputs 0 — 9
}
xdeepakv
  • 7,835
  • 2
  • 22
  • 32