8

I have this setinterval with function alert:

setInterval(function(){
    alert('oo');
}, 5000);

But I would like to change my (5000) interval each time interval runs alert() - I'd like have it randomly selected between 5 - 10 seconds. How can I do it?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
peter
  • 4,289
  • 12
  • 44
  • 67
  • 4
    Don't use `setInterval`, but set a new *timeout* instead after each alert. – deceze Jan 07 '16 at 13:48
  • Does this answer your question? [Randomize setInterval ( How to rewrite same random after random interval)](https://stackoverflow.com/questions/6962658/randomize-setinterval-how-to-rewrite-same-random-after-random-interval) – jabacchetta Feb 19 '20 at 16:03

5 Answers5

26

You should use setTimeout to set interval after which the function should be executed.

function myFunction() {
  var min = 5,
    max = 10;
  var rand = Math.floor(Math.random() * (max - min + 1) + min); //Generate Random number between 5 - 10
  console.log('Wait for ' + rand + ' seconds');
  setTimeout(myFunction, rand * 1000);
}

myFunction()
Satpal
  • 132,252
  • 13
  • 159
  • 168
12

You can do it like this:

function myFunction() {
  alert('oo');
  setTimeout(myFunction, Math.random() * 5000)
}

myFunction()
CoderPi
  • 12,985
  • 4
  • 34
  • 62
  • thank you, brilliant! sorry, I can just mark only one question as answer, but your answer CodeiSir is also great! – peter Jan 07 '16 at 14:15
7

You can do this with two methods, first setTimeout and second requestAnimationFrame.

Here are the full examples of both.

Random interval with setTimeout

function randomInterval(callback, min, max) {
    let timeout;

    const randomNum = (max, min = 0) => Math.random() * (max - min) + min;

    const stop = () => clearTimeout(timeout)

    const tick = () => {
        let time = randomNum(min, max);
        stop();

        timeout = setTimeout(() => {
            tick();
            callback && typeof callback === "function" && callback(stop);
        }, time)
    }

    tick();
}

Random interval using requestAnimationFrame

function randomInterval(callback, min, max) {
    const randomNum = (max, min = 0) => Math.random() * (max - min) + min;

    let targetTime = randomNum(min, max);
    let lastInvoke = performance.now();

    const stop = () => targetTime = null

    const tick = () => {
        if (!targetTime) return;

        if (performance.now() - lastInvoke > targetTime) {
            lastInvoke = performance.now();
            targetTime = randomNum(min, max);
            callback && typeof callback === "function" && callback(stop);
        }

        requestAnimationFrame(tick)
    }

    tick();
}

and here is an example of how to call it

randomInterval((stop) => {
    // do what you want...

    if (stopCondition) {
        stop();
    }
}, 1000, 3000)
Behnam Azimi
  • 2,260
  • 3
  • 34
  • 52
1

Intervals, once set, are fixed.

Use setTimeout and call the function recursively instead.

function myAlert() {
    setTimeout(myAlert, generate_random_time());
    alert('oo');
}
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
0

The only potential issue with most of the current answers here is that the initial function call does not have the random delay, only the subsequent calls.

A modification is to place the function outside the loop then call it inside the setTimeout:

function doSomething() {
    console.log("Hello");
}

(function loop() {
    var rand = Math.round(Math.random() * 10);
    setTimeout(function() {
            doSomething();
            console.log("Delayed " + rand + " secs.");
            loop();  
    }, rand*1000);
}());

Learning ES6 converting to arrow functions and template literals the code looks like:

function doSomething() {
    console.log("Hello");
}

(function loop() {
    let rand = Math.round(Math.random() * 10);
    setTimeout( () => {
            doSomething();
            console.log(`Delayed ${rand} secs`);
            loop();  
    }, rand*1000);
}());

Adapted from a very similar thread:https://stackoverflow.com/questions/6962658/randomize-setinterval-how-to-rewrite-same-random-after-random-interval