How to get clearInterval() to work in a loop in JavaScript - javascript

So I'm trying to get a function to run once every second, and then after four seconds I want it to stop using clearInterval()
function dotdotdot(){
var x = 0;
setInterval(function(){
if (x>=3){
torpWri = torpWri + ".";
document.getElementById("torpTxt").innerHTML = torpWri;
x++;
}
else{
x = 0;
clearInterval();
}
},1000);
}
This is my function and it should stop after four seconds and then reset x to 0 for when I call it again.
function loadButton(){
torpWri = "Torpedo Loading"
if(torpLoadAmount[arNum]<5){
torpLoadAmount[arNum]++;
torpAmount--;
document.getElementById("torpCnt").innerHTML = torpAmount;
document.getElementById("torpTxt").style.visibility = "visible";
document.getElementById("butunload").disabled=true;
document.getElementById("butfire").disabled=true;
document.getElementById("torpTxt").innerHTML = torpWri;
dotdotdot();
}
else{
document.getElementById("torpTxt").style.visibility = "visible";
document.getElementById("torpTxt").innerHTML = "Torpedo Bay Full";
}
timer3();
}
This is how I'm calling it.
I'm just needed to know why it isn't running the function dotdotdot(); every second and then stopping after four. Then when I call it again it should all just reset. But it's not running...
I've been searching for a while and haven't found anything, so I came here.
(Also, please don't comment on my other code, I know there are probably easier ways to do it, but this is what I'm working with right now.)

setInterval returns a timerID, which needs to be passed to clearInterval.
var ticks = 0;
var intervalID = setInterval(function() {
if (++ticks == 4) {
clearInterval(intervalID);
}
}, 1000);
You could also use setTimeout instead, and just not schedule a new tick when the condition is met.
setTimeout(function callback(ticks) {
if (ticks > limit) {
return;
}
setTimeout(callback, 0, ++ticks);
}, 1000, 0)

You need to store the handle / intervalId for the interval when it is set and then use it when you want to clear the interval:
function dotdotdot(){
var x = 0;
var intervalId = -1;
intervalId = setInterval(function(){
if (x>=3){
torpWri = torpWri + ".";
document.getElementById("torpTxt").innerHTML = torpWri;
x++;
} else {
x = 0;
clearInterval(intervalId);
}
},1000);
}
More info: https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Timers

setInterval will return a timerid. So do like
var timer = setInterval(fun......)
Then
clearInterval(timer)

Related

Can't use variable as setInterval delay? [duplicate]

I have written a javascript function that uses setInterval to manipulate a string every tenth of a second for a certain number of iterations.
function timer() {
var section = document.getElementById('txt').value;
var len = section.length;
var rands = new Array();
for (i=0; i<len; i++) {
rands.push(Math.floor(Math.random()*len));
};
var counter = 0
var interval = setInterval(function() {
var letters = section.split('');
for (j=0; j < len; j++) {
if (counter < rands[j]) {
letters[j] = Math.floor(Math.random()*9);
};
};
document.getElementById('txt').value = letters.join('');
counter++
if (counter > rands.max()) {
clearInterval(interval);
}
}, 100);
};
Instead of having the interval set at a specific number, I would like to update it every time it runs, based on a counter. So instead of:
var interval = setInterval(function() { ... }, 100);
It would be something like:
var interval = setInterval(function() { ... }, 10*counter);
Unfortunately, that did not work. It seemed like "10*counter" equals 0.
So, how can I adjust the interval every time the anonymous function runs?
You could use an anonymous function:
var counter = 10;
var myFunction = function(){
clearInterval(interval);
counter *= 10;
interval = setInterval(myFunction, counter);
}
var interval = setInterval(myFunction, counter);
UPDATE: As suggested by A. Wolff, use setTimeout to avoid the need for clearInterval.
var counter = 10;
var myFunction = function() {
counter *= 10;
setTimeout(myFunction, counter);
}
setTimeout(myFunction, counter);
Use setTimeout() instead. The callback would then be responsible for firing the next timeout, at which point you can increase or otherwise manipulate the timing.
EDIT
Here's a generic function you can use to apply a "decelerating" timeout for ANY function call.
function setDeceleratingTimeout(callback, factor, times)
{
var internalCallback = function(tick, counter) {
return function() {
if (--tick >= 0) {
window.setTimeout(internalCallback, ++counter * factor);
callback();
}
}
}(times, 0);
window.setTimeout(internalCallback, factor);
};
// console.log() requires firebug
setDeceleratingTimeout(function(){ console.log('hi'); }, 10, 10);
setDeceleratingTimeout(function(){ console.log('bye'); }, 100, 10);
I like this question - inspired a little timer object in me:
window.setVariableInterval = function(callbackFunc, timing) {
var variableInterval = {
interval: timing,
callback: callbackFunc,
stopped: false,
runLoop: function() {
if (variableInterval.stopped) return;
var result = variableInterval.callback.call(variableInterval);
if (typeof result == 'number')
{
if (result === 0) return;
variableInterval.interval = result;
}
variableInterval.loop();
},
stop: function() {
this.stopped = true;
window.clearTimeout(this.timeout);
},
start: function() {
this.stopped = false;
return this.loop();
},
loop: function() {
this.timeout = window.setTimeout(this.runLoop, this.interval);
return this;
}
};
return variableInterval.start();
};
Example use
var vi = setVariableInterval(function() {
// this is the variableInterval - so we can change/get the interval here:
var interval = this.interval;
// print it for the hell of it
console.log(interval);
// we can stop ourselves.
if (interval>4000) this.stop();
// we could return a new interval after doing something
return interval + 100;
}, 100);
// we can change the interval down here too
setTimeout(function() {
vi.interval = 3500;
}, 1000);
// or tell it to start back up in a minute
setTimeout(function() {
vi.interval = 100;
vi.start();
}, 60000);
I had the same question as the original poster, did this as a solution. Not sure how efficient this is ....
let interval = 5000; // initial condition
let run = setInterval(request, interval); // start setInterval as "run"
function request() {
console.log(interval); // firebug or chrome log
clearInterval(run); // stop the setInterval()
// dynamically change the run interval
if (interval > 200) {
interval = interval * .8;
} else {
interval = interval * 1.2;
}
run = setInterval(request, interval); // start the setInterval()
}
This is my way of doing this, i use setTimeout:
var timer = {
running: false,
iv: 5000,
timeout: false,
cb : function(){},
start : function(cb,iv){
var elm = this;
clearInterval(this.timeout);
this.running = true;
if(cb) this.cb = cb;
if(iv) this.iv = iv;
this.timeout = setTimeout(function(){elm.execute(elm)}, this.iv);
},
execute : function(e){
if(!e.running) return false;
e.cb();
e.start();
},
stop : function(){
this.running = false;
},
set_interval : function(iv){
clearInterval(this.timeout);
this.start(false, iv);
}
};
Usage:
timer.start(function(){
console.debug('go');
}, 2000);
timer.set_interval(500);
timer.stop();
A much simpler way would be to have an if statement in the refreshed function and a control to execute your command at regular time intervals . In the following example, I run an alert every 2 seconds and the interval (intrv) can be changed dynamically...
var i=1;
var intrv=2; // << control this variable
var refreshId = setInterval(function() {
if(!(i%intrv)) {
alert('run!');
}
i++;
}, 1000);
This can be initiated however you want. timeout is the method i used to keep it on the top of the hour.
I had the need for every hour to begin a code block on the hour. So this would start at server startup and run the interval hourly. Basicaly the initial run is to begin the interval within the same minute. So in a second from init, run immediately then on every 5 seconds.
var interval = 1000;
var timing =function(){
var timer = setInterval(function(){
console.log(interval);
if(interval == 1000){ /*interval you dont want anymore or increment/decrement */
interval = 3600000; /* Increment you do want for timer */
clearInterval(timer);
timing();
}
},interval);
}
timing();
Alternately if you wanted to just have something happen at start and then forever at a specific interval you could just call it at the same time as the setInterval. For example:
var this = function(){
//do
}
setInterval(function(){
this()
},3600000)
this()
Here we have this run the first time and then every hour.
I couldn't synchronize and change the speed my setIntervals too and I was about to post a question. But I think I've found a way. It should certainly be improved because I'm a beginner. So, I'd gladly read your comments/remarks about this.
<body onload="foo()">
<div id="count1">0</div>
<div id="count2">2nd counter is stopped</div>
<button onclick="speed0()">pause</button>
<button onclick="speedx(1)">normal speed</button>
<button onclick="speedx(2)">speed x2</button>
<button onclick="speedx(4)">speed x4</button>
<button onclick="startTimer2()">Start second timer</button>
</body>
<script>
var count1 = 0,
count2 = 0,
greenlight = new Boolean(0), //blocks 2nd counter
speed = 1000, //1second
countingSpeed;
function foo(){
countingSpeed = setInterval(function(){
counter1();
counter2();
},speed);
}
function counter1(){
count1++;
document.getElementById("count1").innerHTML=count1;
}
function counter2(){
if (greenlight != false) {
count2++;
document.getElementById("count2").innerHTML=count2;
}
}
function startTimer2(){
//while the button hasn't been clicked, greenlight boolean is false
//thus, the 2nd timer is blocked
greenlight = true;
counter2();
//counter2() is greenlighted
}
//these functions modify the speed of the counters
function speed0(){
clearInterval(countingSpeed);
}
function speedx(a){
clearInterval(countingSpeed);
speed=1000/a;
foo();
}
</script>
If you want the counters to begin to increase once the page is loaded, put counter1() and counter2() in foo() before countingSpeed is called. Otherwise, it takes speed milliseconds before execution.
EDIT : Shorter answer.
(function variableInterval() {
//whatever needs to be done
interval *= 2; //deal with your interval
setTimeout(variableInterval, interval);
//whatever needs to be done
})();
can't get any shorter
Here is yet another way to create a decelerating/accelerating interval timer. The interval gets multiplied by a factor until a total time is exceeded.
function setChangingInterval(callback, startInterval, factor, totalTime) {
let remainingTime = totalTime;
let interval = startInterval;
const internalTimer = () => {
remainingTime -= interval ;
interval *= factor;
if (remainingTime >= 0) {
setTimeout(internalTimer, interval);
callback();
}
};
internalTimer();
}
Make new function:
// set Time interval
$("3000,18000").Multitimeout();
jQuery.fn.extend({
Multitimeout: function () {
var res = this.selector.split(",");
$.each(res, function (index, val) { setTimeout(function () {
//...Call function
temp();
}, val); });
return true;
}
});
function temp()
{
alert();
}
This piece of code below accelerates (acceleration > 1) or decelerates (acceleration <1) a setInterval function :
function accelerate(yourfunction, timer, refresh, acceleration) {
var new_timer = timer / acceleration;
var refresh_init = refresh;//save this user defined value
if (refresh < new_timer ){//avoid reseting the interval before it has produced anything.
refresh = new_timer + 1 ;
};
var lastInter = setInterval(yourfunction, new_timer);
console.log("timer:", new_timer);
function stopLastInter() {
clearInterval(lastInter);
accelerate(yourfunction, new_timer, refresh_init, acceleration);
console.log("refresh:", refresh);
};
setTimeout(stopLastInter, refresh);
}
With :
timer: the setInterval initial value in ms (increasing or decreasing)
refresh: the time before a new value of timer is calculated. This is the step lenght
acceleration: the gap between the old and the next timer value. This is the step height
Inspired by the internal callback above, i made a function to fire a callback at fractions of minutes. If timeout is set to intervals like 6 000, 15 000, 30 000, 60 000 it will continuously adapt the intervals in sync to the exact transition to the next minute of your system clock.
//Interval timer to trigger on even minute intervals
function setIntervalSynced(callback, intervalMs) {
//Calculate time to next modulus timer event
var betterInterval = function () {
var d = new Date();
var millis = (d.getMinutes() * 60 + d.getSeconds()) * 1000 + d.getMilliseconds();
return intervalMs - millis % intervalMs;
};
//Internal callback
var internalCallback = function () {
return function () {
setTimeout(internalCallback, betterInterval());
callback();
}
}();
//Initial call to start internal callback
setTimeout(internalCallback, betterInterval());
};
This is my idea for times when you do not want loops like setInterval to overlap.
You also want to be able to set the loop execution delay and start and stop the loop, instansly on the fly.
I am using a loop_flag variable and a setTimeout function.
I set the main function to async so that you can call other functions in the body by calling await. When the main body of your code is running, the main loop waits and does not repeat itself. (which is not the case with setInterval)
An example of a simple code is:
//#NabiKAZ
document.getElementById("btn_start").addEventListener("click", function() {
console.log("Starting...");
loop_flag = true;
loop_func();
});
document.getElementById("btn_stop").addEventListener("click", function() {
console.log("Stoping...");
loop_flag = false;
});
var n = 0;
var loop_flag = false;
var loop_func = async function() {
if (!loop_flag) {
console.log("STOP.");
return;
}
//body main function inhere
n++;
console.log(n);
////
if (loop_flag) {
setTimeout(loop_func, document.getElementById("inp_delay").value);
} else {
console.log("STOP.");
}
}
<input id="inp_delay" value="1000">
<button id="btn_start">START</button>
<button id="btn_stop">STOP</button>
For a more complete code with a fetch request inside the loop, see here:
https://jsfiddle.net/NabiKAZ/a5hdw2bo/
You can use a variable and change the variable instead.
setInterval(() => function, variable)
You can do this by clearing the interval every iteration, changing the timer value and setting the interval again. Hope it helps ;)
For exemple:
const DOMCounter = document.querySelector(".counter")
let timer = 1000
const changeCounter = () => {
clearInterval(interval)
DOMCounter.innerHTML = timer
timer += 1000
timer == 5000 && timer == 1000
interval = setInterval(changeCounter, timer)
}
let interval = setInterval(changeCounter, timer)
<div class="container">
<p class="counter"></p>
</div>
var counter = 15;
var interval = function() {
setTimeout(function(){
// Write your code here and remove console.log, remember that you need declare yourDynamicValue and give it a value
console.log((new Date()).getTime())
window.counter = yourDynamicValue;
window.interval();
}, counter);
}
// It needs to run just once as init
interval();

clearing interval after counter reach 0 or reset

I'm trying to make simple game but I have problem to manage counter and to clear interval after counter reaches 0 or I click reset button. It works when It reaches 0, but when I try to implement it to reset button, counter is reseting but then goes with double speed.
let counter = 60;
let healthPoints = 3;
let points = 0;
document.querySelector('.reset').addEventListener('click', resetGame);
function countTime() {
const timer = document.querySelector('.timer');
const countTime = setInterval(function () {
counter--;
timer.innerHTML = + counter;
if (counter == 0) {
alert('Game over')
clearInterval(countTime);
}
}, 1000)
}
function resetGame() {
newBoard();
counter = 60;
healthPoints = 4;
points = 0;
clearInterval(countTime);
}
The countTime argument your are passing to the clearInterval function inside the resetGame function is a reference to the function called countTime. You need to rename the variable and declare it globally:
let counter = 60;
let healthPoints = 3;
let points = 0;
let t = null;
document.querySelector('.reset').addEventListener('click', resetGame);
function countTime() {
const timer = document.querySelector('.timer');
t = setInterval(function () {
counter--;
timer.innerHTML = + counter;
if (counter == 0) {
alert('Game over')
clearInterval(t);
}
}, 1000)
}
function resetGame() {
newBoard();
counter = 60;
healthPoints = 4;
points = 0;
clearInterval(t);
}
setInterval returns a value that you pass to clearInterval() when you want to stop the timer. You need to save this in a scope where resetGame() can see it. You are declaring inside countTime() which means it's only in scope there.
Here I've named it interval and defined it outside both functions so both functions have access to it:
let counter = 60;
let healthPoints = 3;
let points = 0;
let interval;
document.querySelector('.reset').addEventListener('click', resetGame);
function countTime() {
const timer = document.querySelector('.timer');
interval = setInterval(function () {
counter--;
timer.innerHTML = + counter;
if (counter == 0) {
alert('Game over')
clearInterval(interval);
}
}, 1000)
}
function resetGame() {
counter = 60;
healthPoints = 4;
points = 0;
clearInterval(interval);
countTime()
}
countTime()
<button class="reset">Reset</button>
<div class = "timer"></div>
It is because you didn't actually cleared the interval, you must provide to the clearInterval function which needs an interval id in order to know which interval to clear. See https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearInterval
This id is actually returned when you call the setInterval function, so your countTime variable is your interval ID.
This is why when it reaches zero it works it is because you are properly clearing the interval by provided its id to the clearInterval function and on the contrary you are just providing the function reference to the clearInterval function in your resetGame function
So what you can do is actually returning your intervalId from your countTime and provided this to your resetGame function :
function countTime() {
...
const timer = document.querySelector('.timer');
// I renamed it just to be clear
const countTimeIntervalID = setInterval(function () {
counter--;
timer.innerHTML = + counter;
if (counter == 0) {
alert('Game over')
clearInterval(countTime);
}
}, 1000)
return countTimeIntervalID
}
let countTimeIntervalID = countTime();
function resetGame() {
...
clearInterval(countTimeIntervalID);
}
Also, note that the reason why when you clicked the reset button it doubled the counter time it is because since you didn't clear the first one, it was still running so there were actually to intervals running and updating the same .timer dom element

Confused about SetInterval and closures

How can we repeatedly update the contents of a div using setInterval
I am using the question from this link as a reference How to repeatedly update the contents of a <div> by only using JavaScript?
but i have got few questions here
Can we do it without anonymous functions,using closures. I have tried but could not end up with any workable solution.
How can we make it run infinitely, with the following code it gets stopped once i reaches 10.
window.onload = function() {
var timing = document.getElementById("timer");
var i = 0;
var interval = setInterval(function() {
timing.innerHTML = i++;
if (i > 10) {
clearInterval(interval);
i = 0;
return;
}
}, 1000);
}
<div id="timer"></div>
I am confused about setIntervals and closures
can some one help me here
Thanks
You could do something like this with a closure. Just reset your i value so, you will always be within your given range.
window.onload = function() {
var updateContent = (function(idx) {
return function() {
if (idx === 10) {
idx = 0;
}
var timing = document.getElementById("timer");
timing.innerHTML = idx++;
}
})(0);
var interval = setInterval(updateContent, 1000);
}
<div id="timer"></div>
This one should be clearer.
function updateTimer() {
var timer = document.getElementById("timer");
var timerValue = parseInt(timer.getAttribute("data-timer-value")) + 1;
if (timerValue == 10) {
timerValue = 0;
}
timer.setAttribute("data-timer-value", timerValue);
timer.innerHTML = "the time is " + timerValue;
}
window.onload = function() {
setInterval(updateTimer, 1000);
}
<div id="timer" data-timer-value="0"></div>

Creating a continuous counter with Javascript?

function lemath()
{
var count;
count = 0;
stuff.innerHTML = "stuff" + count;
}
function begin()
{
lemath();
setTimeout(function() {
begin();
}, 1000);
}
I'm trying to create an infinite loop that will count each time it loops and display it, but when I do the code above it just gives back undefined?
Thank you very much with the help! :)
var count = 0; // declaring "count" here makes the variable globally available
function lemath()
{
count++;
var stuff = document.getElementById('stuff');
stuff.innerHTML = "stuff: " + count;
}
function begin()
{
lemath();
setTimeout(begin, 1000, window);
}
document.addEventListener('DOMContentLoaded', function () {
begin();
});
Demo: http://jsfiddle.net/pottersky/jj30s2Le/1/
you can use setInterval javascript method for increase your counter
// setInterval(fn, time);
// your counter state should be start from 0
let count = 0;
// Your function should be run each time (for example each second)
const increment = () => {
count++
// show count in console or in DOM
console.log(count)
element.innerHTML = count
}
setInterval(increment, 1000);
For Performance reason and for stop or reset timer you can use clearInterval method
const timer = setInterval(increment, 1000);
// stop counter
clearInterval(timer)

Changing the interval of SetInterval while it's running

I have written a javascript function that uses setInterval to manipulate a string every tenth of a second for a certain number of iterations.
function timer() {
var section = document.getElementById('txt').value;
var len = section.length;
var rands = new Array();
for (i=0; i<len; i++) {
rands.push(Math.floor(Math.random()*len));
};
var counter = 0
var interval = setInterval(function() {
var letters = section.split('');
for (j=0; j < len; j++) {
if (counter < rands[j]) {
letters[j] = Math.floor(Math.random()*9);
};
};
document.getElementById('txt').value = letters.join('');
counter++
if (counter > rands.max()) {
clearInterval(interval);
}
}, 100);
};
Instead of having the interval set at a specific number, I would like to update it every time it runs, based on a counter. So instead of:
var interval = setInterval(function() { ... }, 100);
It would be something like:
var interval = setInterval(function() { ... }, 10*counter);
Unfortunately, that did not work. It seemed like "10*counter" equals 0.
So, how can I adjust the interval every time the anonymous function runs?
You could use an anonymous function:
var counter = 10;
var myFunction = function(){
clearInterval(interval);
counter *= 10;
interval = setInterval(myFunction, counter);
}
var interval = setInterval(myFunction, counter);
UPDATE: As suggested by A. Wolff, use setTimeout to avoid the need for clearInterval.
var counter = 10;
var myFunction = function() {
counter *= 10;
setTimeout(myFunction, counter);
}
setTimeout(myFunction, counter);
Use setTimeout() instead. The callback would then be responsible for firing the next timeout, at which point you can increase or otherwise manipulate the timing.
EDIT
Here's a generic function you can use to apply a "decelerating" timeout for ANY function call.
function setDeceleratingTimeout(callback, factor, times)
{
var internalCallback = function(tick, counter) {
return function() {
if (--tick >= 0) {
window.setTimeout(internalCallback, ++counter * factor);
callback();
}
}
}(times, 0);
window.setTimeout(internalCallback, factor);
};
// console.log() requires firebug
setDeceleratingTimeout(function(){ console.log('hi'); }, 10, 10);
setDeceleratingTimeout(function(){ console.log('bye'); }, 100, 10);
I like this question - inspired a little timer object in me:
window.setVariableInterval = function(callbackFunc, timing) {
var variableInterval = {
interval: timing,
callback: callbackFunc,
stopped: false,
runLoop: function() {
if (variableInterval.stopped) return;
var result = variableInterval.callback.call(variableInterval);
if (typeof result == 'number')
{
if (result === 0) return;
variableInterval.interval = result;
}
variableInterval.loop();
},
stop: function() {
this.stopped = true;
window.clearTimeout(this.timeout);
},
start: function() {
this.stopped = false;
return this.loop();
},
loop: function() {
this.timeout = window.setTimeout(this.runLoop, this.interval);
return this;
}
};
return variableInterval.start();
};
Example use
var vi = setVariableInterval(function() {
// this is the variableInterval - so we can change/get the interval here:
var interval = this.interval;
// print it for the hell of it
console.log(interval);
// we can stop ourselves.
if (interval>4000) this.stop();
// we could return a new interval after doing something
return interval + 100;
}, 100);
// we can change the interval down here too
setTimeout(function() {
vi.interval = 3500;
}, 1000);
// or tell it to start back up in a minute
setTimeout(function() {
vi.interval = 100;
vi.start();
}, 60000);
I had the same question as the original poster, did this as a solution. Not sure how efficient this is ....
let interval = 5000; // initial condition
let run = setInterval(request, interval); // start setInterval as "run"
function request() {
console.log(interval); // firebug or chrome log
clearInterval(run); // stop the setInterval()
// dynamically change the run interval
if (interval > 200) {
interval = interval * .8;
} else {
interval = interval * 1.2;
}
run = setInterval(request, interval); // start the setInterval()
}
This is my way of doing this, i use setTimeout:
var timer = {
running: false,
iv: 5000,
timeout: false,
cb : function(){},
start : function(cb,iv){
var elm = this;
clearInterval(this.timeout);
this.running = true;
if(cb) this.cb = cb;
if(iv) this.iv = iv;
this.timeout = setTimeout(function(){elm.execute(elm)}, this.iv);
},
execute : function(e){
if(!e.running) return false;
e.cb();
e.start();
},
stop : function(){
this.running = false;
},
set_interval : function(iv){
clearInterval(this.timeout);
this.start(false, iv);
}
};
Usage:
timer.start(function(){
console.debug('go');
}, 2000);
timer.set_interval(500);
timer.stop();
A much simpler way would be to have an if statement in the refreshed function and a control to execute your command at regular time intervals . In the following example, I run an alert every 2 seconds and the interval (intrv) can be changed dynamically...
var i=1;
var intrv=2; // << control this variable
var refreshId = setInterval(function() {
if(!(i%intrv)) {
alert('run!');
}
i++;
}, 1000);
This can be initiated however you want. timeout is the method i used to keep it on the top of the hour.
I had the need for every hour to begin a code block on the hour. So this would start at server startup and run the interval hourly. Basicaly the initial run is to begin the interval within the same minute. So in a second from init, run immediately then on every 5 seconds.
var interval = 1000;
var timing =function(){
var timer = setInterval(function(){
console.log(interval);
if(interval == 1000){ /*interval you dont want anymore or increment/decrement */
interval = 3600000; /* Increment you do want for timer */
clearInterval(timer);
timing();
}
},interval);
}
timing();
Alternately if you wanted to just have something happen at start and then forever at a specific interval you could just call it at the same time as the setInterval. For example:
var this = function(){
//do
}
setInterval(function(){
this()
},3600000)
this()
Here we have this run the first time and then every hour.
I couldn't synchronize and change the speed my setIntervals too and I was about to post a question. But I think I've found a way. It should certainly be improved because I'm a beginner. So, I'd gladly read your comments/remarks about this.
<body onload="foo()">
<div id="count1">0</div>
<div id="count2">2nd counter is stopped</div>
<button onclick="speed0()">pause</button>
<button onclick="speedx(1)">normal speed</button>
<button onclick="speedx(2)">speed x2</button>
<button onclick="speedx(4)">speed x4</button>
<button onclick="startTimer2()">Start second timer</button>
</body>
<script>
var count1 = 0,
count2 = 0,
greenlight = new Boolean(0), //blocks 2nd counter
speed = 1000, //1second
countingSpeed;
function foo(){
countingSpeed = setInterval(function(){
counter1();
counter2();
},speed);
}
function counter1(){
count1++;
document.getElementById("count1").innerHTML=count1;
}
function counter2(){
if (greenlight != false) {
count2++;
document.getElementById("count2").innerHTML=count2;
}
}
function startTimer2(){
//while the button hasn't been clicked, greenlight boolean is false
//thus, the 2nd timer is blocked
greenlight = true;
counter2();
//counter2() is greenlighted
}
//these functions modify the speed of the counters
function speed0(){
clearInterval(countingSpeed);
}
function speedx(a){
clearInterval(countingSpeed);
speed=1000/a;
foo();
}
</script>
If you want the counters to begin to increase once the page is loaded, put counter1() and counter2() in foo() before countingSpeed is called. Otherwise, it takes speed milliseconds before execution.
EDIT : Shorter answer.
(function variableInterval() {
//whatever needs to be done
interval *= 2; //deal with your interval
setTimeout(variableInterval, interval);
//whatever needs to be done
})();
can't get any shorter
Here is yet another way to create a decelerating/accelerating interval timer. The interval gets multiplied by a factor until a total time is exceeded.
function setChangingInterval(callback, startInterval, factor, totalTime) {
let remainingTime = totalTime;
let interval = startInterval;
const internalTimer = () => {
remainingTime -= interval ;
interval *= factor;
if (remainingTime >= 0) {
setTimeout(internalTimer, interval);
callback();
}
};
internalTimer();
}
Make new function:
// set Time interval
$("3000,18000").Multitimeout();
jQuery.fn.extend({
Multitimeout: function () {
var res = this.selector.split(",");
$.each(res, function (index, val) { setTimeout(function () {
//...Call function
temp();
}, val); });
return true;
}
});
function temp()
{
alert();
}
This piece of code below accelerates (acceleration > 1) or decelerates (acceleration <1) a setInterval function :
function accelerate(yourfunction, timer, refresh, acceleration) {
var new_timer = timer / acceleration;
var refresh_init = refresh;//save this user defined value
if (refresh < new_timer ){//avoid reseting the interval before it has produced anything.
refresh = new_timer + 1 ;
};
var lastInter = setInterval(yourfunction, new_timer);
console.log("timer:", new_timer);
function stopLastInter() {
clearInterval(lastInter);
accelerate(yourfunction, new_timer, refresh_init, acceleration);
console.log("refresh:", refresh);
};
setTimeout(stopLastInter, refresh);
}
With :
timer: the setInterval initial value in ms (increasing or decreasing)
refresh: the time before a new value of timer is calculated. This is the step lenght
acceleration: the gap between the old and the next timer value. This is the step height
Inspired by the internal callback above, i made a function to fire a callback at fractions of minutes. If timeout is set to intervals like 6 000, 15 000, 30 000, 60 000 it will continuously adapt the intervals in sync to the exact transition to the next minute of your system clock.
//Interval timer to trigger on even minute intervals
function setIntervalSynced(callback, intervalMs) {
//Calculate time to next modulus timer event
var betterInterval = function () {
var d = new Date();
var millis = (d.getMinutes() * 60 + d.getSeconds()) * 1000 + d.getMilliseconds();
return intervalMs - millis % intervalMs;
};
//Internal callback
var internalCallback = function () {
return function () {
setTimeout(internalCallback, betterInterval());
callback();
}
}();
//Initial call to start internal callback
setTimeout(internalCallback, betterInterval());
};
This is my idea for times when you do not want loops like setInterval to overlap.
You also want to be able to set the loop execution delay and start and stop the loop, instansly on the fly.
I am using a loop_flag variable and a setTimeout function.
I set the main function to async so that you can call other functions in the body by calling await. When the main body of your code is running, the main loop waits and does not repeat itself. (which is not the case with setInterval)
An example of a simple code is:
//#NabiKAZ
document.getElementById("btn_start").addEventListener("click", function() {
console.log("Starting...");
loop_flag = true;
loop_func();
});
document.getElementById("btn_stop").addEventListener("click", function() {
console.log("Stoping...");
loop_flag = false;
});
var n = 0;
var loop_flag = false;
var loop_func = async function() {
if (!loop_flag) {
console.log("STOP.");
return;
}
//body main function inhere
n++;
console.log(n);
////
if (loop_flag) {
setTimeout(loop_func, document.getElementById("inp_delay").value);
} else {
console.log("STOP.");
}
}
<input id="inp_delay" value="1000">
<button id="btn_start">START</button>
<button id="btn_stop">STOP</button>
For a more complete code with a fetch request inside the loop, see here:
https://jsfiddle.net/NabiKAZ/a5hdw2bo/
You can use a variable and change the variable instead.
setInterval(() => function, variable)
You can do this by clearing the interval every iteration, changing the timer value and setting the interval again. Hope it helps ;)
For exemple:
const DOMCounter = document.querySelector(".counter")
let timer = 1000
const changeCounter = () => {
clearInterval(interval)
DOMCounter.innerHTML = timer
timer += 1000
timer == 5000 && timer == 1000
interval = setInterval(changeCounter, timer)
}
let interval = setInterval(changeCounter, timer)
<div class="container">
<p class="counter"></p>
</div>
var counter = 15;
var interval = function() {
setTimeout(function(){
// Write your code here and remove console.log, remember that you need declare yourDynamicValue and give it a value
console.log((new Date()).getTime())
window.counter = yourDynamicValue;
window.interval();
}, counter);
}
// It needs to run just once as init
interval();

Categories

Resources