AdamJones
AdamJones

Reputation: 601

How to make the refresh frequency of setTimeout a variable?

I want a function I am writing to call itself automatically. I want to be able to parse the frequency at which it calls itself via the first time I parse it. It would then use that same value internally with the JS setTimeout() function to call itself repeatedly again at the same frequency.

So you can see what I have in the sample below:

function testFunction(refreshFrequ){
    setTimeout(function() {
        console.log("frequency: "+refreshFrequ);
        testFunction(refreshFrequ);
    }, refreshFrequ);
}

// run the 1st time
testFunction(5000);

The problem is that this doesn't work as from the second time it runs onwards the parsed timeout isn't evaluated. The console output gives a clue to what's going on here:

frequency: undefined

How would I get this working, nothing so far has helped.

Upvotes: 2

Views: 323

Answers (2)

Brie
Brie

Reputation: 66

Try Window setInterval() Method instead. Also see this answer and this answer for more information.

var autoInterval;
var elapsed = 0;

function myStartFunction(refreshFrequ) {
  if (!autoInterval) {
    autoInterval = setInterval(function() {
      elapsed++;
      document.getElementById("txt").innerHTML = refreshFrequ * elapsed + " elapsed.";
      console.log("frequency interval: " + refreshFrequ + " x " + elapsed);
    }, refreshFrequ);
  }
}

function myStopFunction() {
  if (autoInterval) {
    clearInterval(autoInterval);
    autoInterval = null;
    elapsed = 0;
    document.getElementById("txt").innerHTML = "Interval was reset.";
    console.log("interval stopped");
  }
}

myStartFunction(5000);
<p>The setInterval() method has started automatically.</p>

<button onclick="myStartFunction(1000)" title="Start with 1000 ms interval. Clicking this button while the event is active should not create a new interval instance.">Start</button> <button onclick="myStopFunction()" title="Click to stop and clear the interval instance.">Stop</button>

<p id="txt">0 elapsed.</p>

Edit: Although there was no mention of the potential duplicate function calls, the other answer should be taken into consideration, especially if the event can arbitrarily be executed. The if statement was imposed in order to prevent duplicate events from being stacked up against the original instance; otherwise, each additionally executed function would result in a unique instance, which could then further create unstoppable multiple events, so I must give credit where credit is due. Kudos to Tymek!

Upvotes: 3

Tymek
Tymek

Reputation: 3113

You might want to use setInterval instead.

var testFunction = (function () { // This will "build"/"enclose" our function
    var handle = null; // ID of the interval
    return function (freq) {
      if (handle !== null) clearInterval(handle);
      handle = setInterval(function() {
        console.log("frequency: " + freq);
      }, freq);
    };
})();

With this if you re-initialize interval, you will not create another instance of it (having 2 functions ticking).

You can learn more about setInterval at: https://www.w3schools.com/jsref/met_win_setinterval.asp and more about how JavaScript functions works at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

Upvotes: 1

Related Questions