Why is math.random not working

I have this number countdown script but can’t get the Math.random() to generate a random number to generate a non consistent count down delay between countdown It counts down at exactly 2 sec interval at the moment.

I need the interval to be a random time delay

<script>
var timeleft = 479;
var downloadTimer = setInterval(function(){
  
  if(timeleft <= 470){
    clearInterval(downloadTimer);
    document.getElementById("countdown").innerHTML = "470";
  } 
  
  else {
    document.getElementById("countdown").innerHTML = timeleft;
  }
  
  timeleft -= 1;
}, 2000 + Math.random() * 100);

</script>

<div id="countdown"></div>

Because the js implementation of math.random returns a number between 0 and 1 so at best are going to get is just under 2100 milliseconds (2000 + .999 * 100 or 2099), but never better than that.

1 Like

Between what and what?

As Dave points out, Math.random() is a float between 0 and 1. So the general form of getting an integer between A and B is:
Math.floor(Math.random()*(B-A+1)+A) (or cast to int rather than Math.floor, depending on your need)

OK I understand, but I used it in the following sernario and it actually work so what is the difference

<span id="countdown"></span>
<script>
var timeleft = 479;

function countdown() {
    
    document.getElementById('countdown').innerHTML = timeleft;
    if (timeleft--) {
        
        
    }
    setTimeout(countdown, 2000 + Math.random() * 8000);
}

window.onload = countdown;
</script>

Oh wait, I think I see what you’re trying to do, and why it’s not working.
I misunderstood your original post. Apologies.

setInterval doesnt re-evaluate the timer on every loop - it resolved your random value, came up with a number (somewhere in the range of 2000-2099), and said “every X milliseconds, run this function.”

What you’re doing here, is start a function. That function sets a new timer, which re-evaluates the random modifier, every loop.

1 Like

What do you see different here? The multiplier is a factor of 80 higher.

With math.random, the highest you can get is .99999999 (to 64 places - I think),

So with 2000 + Math.random() * 100, the highest value you can get is 2099.999999*
2000 + .999 * 100
2000 + 99.99999
2099.9999

2099 milliseconds is 2.1 seconds. Not a noticeable difference between 2 seconds and 2.1

Now take your other calculation
2000 + .9999 * 8000
2000 + 7992
9992

9,992 milliseconds is 9.9 seconds, so essentially 10 seconds. That’s a noticeable difference from two seconds.

Well explained, … mili seconds so the random number will always be between 0 and 1 eg .9999 or .0001 so to get the right effect I should increase the multiplier

1 Like

So this scrip works fine i just cant implement

if(timeleft <= 470){
clearInterval(downloadTimer);
document.getElementById(“countdown”).innerHTML = “470”;

just put example in spreadsheet with different random numbers between 0 and 1 do the calculation there will always be a small variant so this will not work

Well if you’re using setTimeout, you have to use clearTimeout as well.

https://www.w3schools.com/Jsref/met_win_cleartimeout.asp

will quickly look at it after my meeting ± 1.5 hours

Hi @johan40, you don’t need to clear anything if you’re using setTimeout(), just don’t start the next one…

var timeLeft = 479

function countdown () {
  console.log(timeLeft)
  timeLeft--
  
  if (timeLeft > 470) {
    setTimeout(countdown, 200 + Math.random() * 100)
  }
}

countdown()

Fun fact: clearTimeout() and clearInterval() can be used interchangeably as their handles are sharing the same pool… although you should of course always use the correct one to avoid readability mayhem. ^^

2 Likes

To clarify, since I wasn’t aware…if I had a setInterval going, I could clearTimeout() it instead of clearInterval?

Yup.

¯\_(ツ)_/¯

1 Like

Woah!

1 Like

so much said but still I am unable to put it together to get random time delay between countdown any other better idea than my starting examples

Got it eventually to work with setTimeout. Thanx for everybody contribution put me into the right direction

<span id="countdown"></span>
<script>
var timeleft = 479;

function countdown() {
    if(timeleft <= 469){
    clearInterval(downloadTimer);
    document.getElementById("countdown").innerHTML = "470";
  }
    else {
    document.getElementById("countdown").innerHTML = timeleft;
  }
  
  timeleft -= 1;
    
    setTimeout(countdown, 2000 + Math.random() * 8000);
}

window.onload = countdown;
</script>

Not really though I’m afraid – the countdown only stops because downloadTimer is not defined, so clearInterval(downloadTimer) will throw a reference error… which is a rather drastic measure at any rate. And if it was defined the countdown would keep going in the background, you’d just not print the current time left to the screen; have a look at post #12 how to actually terminate the countdown.

Which is… accurate, but for the benefit of describing what it is doing, it’s choosing not to do another step in the countdown.

Your countdown timer is, in fact, just a function that decrements a value.

What makes it a timer is the setTimeout, which runs exactly once.
BUT, your function says, “If the value is more than 470, start a NEW timeout, that runs exactly once, and then executes this function again.”

So clearing this Timeout doesnt make any sense - you don’t want to interrupt the timer between cycles, you want to wait until your value has reached a predetermined value, and then simply stop making new timeouts.

A slight difference, but it is an important distinction - interrupting a cycle, rather than logical execution at the end of a cycle.

If I understand you, i have to move

clearInterval(downloadTimer);

to after

setTimeout(countdown, 2000 + Math.random() * 8000);