2

I was in need of a function that repeated it self at a random interval between a certain range of seconds.

I found this one what does what i needed. javascript setinterval with random time

function myFunction() {
  var min = 5,
  max = 10;

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

myFunction()

Problem that i'm having now is how to break in to this function to stop/start it?

Community
  • 1
  • 1
Ingrid trav
  • 35
  • 1
  • 5
  • do you want to clear timeout – CognitiveDesire Mar 28 '17 at 17:20
  • 1
    let myFunction() return the timeoutId returned by setTimeout(), then use `window.clearTimeout(timeoutId)`. [Reference](https://developer.mozilla.org/de/docs/Web/API/WindowTimers/setTimeout) – le_m Mar 28 '17 at 17:21
  • It is a recursive call and won't stop until you use return to get out of the execution loop – Sagar V Mar 28 '17 at 17:22

5 Answers5

2

Encapsulate it into an object that saves the result of setTimeout in a property, so you can call clearTimeout() on it.

function RandomTimeout(min, max, callback) {
  this.min = min;
  this.max = max;
  this.callback = callback;
  var self = this;
  function repeat() {
    var rand = Math.floor(Math.random() * (max - min + 1) + min);
    console.log('Wait for ' + rand + ' seconds');
    self.timer = setTimeout(function() {
      callback();
      repeat();
    }, rand * 1000);
  }
  this.clear = function() {
    console.log("Stopping");
    clearTimeout(this.timer);
  }
  // Start the initial iteration
  repeat();
}

var randTimer = new RandomTimeout(2, 5, function() {
  console.log("Beep");
});

// Stop it in 15 seconds
setTimeout(function() {
  randTimer.clear();
}, 15000);

Unlike the answers with a global variable for the timer, this allows you to have multiple random timers running.

Barmar
  • 741,623
  • 53
  • 500
  • 612
1

You can use clearTimeout, passing the token returned by setTimeout, to stop your random calls.

In the example implementation below, I named the two functions play(min, max) and pause.

var token

function play (min, max) {
  action()
  token = setTimeout(
    play, Math.floor(Math.random()*(max - min) + min),
    min, max
  )
}

function pause () {
  clearTimeout(token)
}

function action () {
  console.log('Example function')
}


play(500, 5000)

// Pause after one minute
setTimeout(pause, 60000)
gyre
  • 16,369
  • 3
  • 37
  • 47
0

May be this will help you

var handle;
function start() {
    var min = 5,
    max = 10;
    var rand = Math.floor(Math.random() * (max - min + 1) + min);
    handle = setTimeout(myFunction, rand * 1000);
}

function stop() {
    clearTimeout(handle);
}

function myFunction() {
    //Your code
}
Kamal Singh
  • 990
  • 8
  • 13
0

I was using a text message to the server which looks at the content of a message to see if there's something in it that is a command.

if(msg.indexOf('addbot') > -1){
        addBotToOnlineListTimer = true;
        addBotToOnlineList();
        return;
        }

    if(msg.indexOf('stopaddbot') > -1){
        addBotToOnlineListTimer = false;            
        return;
        }


function addBotToOnlineList() {
if (addBotToOnlineListTimer == true) {
var min = 5,
max = 10;
var rand = Math.floor(Math.random() * (max - min + 1) + min); //Generate 
Random number between 5 - 10
alert('Wait for ' + rand + ' seconds');
setTimeout(myFunction, rand * 1000);
}else{
return;
}
}

As you can see the first one always evaluates to true.

Sorry to have bothered you all. ;)

Ingrid trav
  • 35
  • 1
  • 5
0

Similar solution with more abstraction:

var token

function timer_action(min, max) {
  let interval = Math.floor(Math.random()*(max - min) + min)
  console.log(interval)
  main_action()
  token = setTimeout(() => {timer_action(min, max)}, interval)
}

function stopTimer() {
  clearTimeout(token)
}

function main_action() {
  console.log('Example function')
}

timer_action(500, 2000)

// stop after 6 seconds
setTimeout(stopTimer, 6000)

isethi
  • 661
  • 1
  • 10
  • 22