How do I use setInterval and clearInterval peoperly? - javascript

I want this timer to count down from 20 and stop at 0. timerFunction() is called on the click of a button.
var time=20;
var clicked=false;
function timeDisplay(){
document.getElementById("timer").innerHTML=
time;
}
function timerFunction(){
if(!clicked){
clicked=true;
if(time>0){
var i=setInterval(function(){
time--;
timeDisplay();
},1000);
}
else{
clearInterval(i);
}
}
}
Right now, the timer works, but it doesn't stop at zero and I don't understand why. Obviously I am very new to this, so any constructive criticism is appreciated.

Firstly your timerFunction is run only once. The statement if(time>0) will execute only once and it will always be true because time is 20 initially.
You ideally want your time variable to be checked after regular intervals. Something you can do inside your timeDisplay function. To enable that, you need to ensure that unique interval id (here intervalName) can be accessed by timeDisplay.
var time=20;
var clicked=false;
var intervalName = null;
function timeDisplay(){
document.getElementById("timer").innerHTML=
time;
if(time == 0){
clearInterval(intervalName);
}
}
function timerFunction(){
if(!clicked){
clicked=true;
intervalName = setInterval(function(){
time--;
timeDisplay();
},1000);
}
}
Note: I have replaced i with intervalName.

Your code has a logic flaw. When you call timerFunction, you set the interval. But since that function is run only once, it will never check your if clause and it also doesn't set the intervall multiple times, as it would have, would it get executed more than once.
Hint: try to check for the time inside the setIntervall callback. I'm not 100% sure, but you can probably clear the intervall inside aswell with something like clearIntervall(this). Maybe you wanna try this out. :)

Actually your if condition is checking for once and when the execution goes inside if it is not checking if condition again so you should have a condition inside interval function checking the value of time variable and clear interval.
`
var time=20;
var clicked=false;
function timeDisplay(){
document.getElementById("timer").innerHTML= time;
}
function timerFunction(){
if(!clicked){
clicked=true;
var i= setInterval(function(){
time--;
if(time == 0){
clearInterval(i);
}
timeDisplay();
},1000);
}
}
`

Related

How to use setInterval to trigger a function so that I can stop it at some point?

So from what I have understood, setInterval() is used to call a function on repeat on regular intervals.
So basically it is a loop that executes a function forever periodically.
I am confused as to if I had to stop this execution at one point what would be the way to do it
for eg I am trying to print the message "hey" 3 times after 1 second each, but somehow it is printing it 3 times every second and is going on forever.
What can I do to stop it after a set number of times.
This is the code that I've been trying
var i = 3;
function message() {
console.log("hey");
}
while(i > 0) {
setInterval(message, 1000);
i = i - 1;
}
Your code is executing the setInterval thrice in the while loop, which is not needed.
Actually, setInterval does not work as a function call but actually registers a function to be called at some interval.
The setInterval() method will continue calling the function until clearInterval() i.e it is deregistered or the process is killed.
It should work like this
var i = 3;
var interval = setInterval(message, 1000);
function message() {
if (i === 0) {
clearInterval(interval);
}
console.log("hey");
i = i - 1;
}
To clear a setInterval, use global clearInterval method.
Example:
var timerId = setInterval(func, 500);
.... some code here....
clearInterval(timerId);
What can I do to stop it after a set number of times.
usually you don't use setInterval() for this, you use setTimeout().
Something like
var counter = 0;
function message() {
console.log("hey");
// we trigger the function again after a second, if not already done 3 times
if (counter < 3) {
setTimeout(message, 1000);
}
counter++;
}
// initial startup after a second, could be faster too
setTimeout(message, 1000);
The setInterval function calls the function indefinitely, whereas setTimeout calls the function once only.
Simply use clearInterval once the count runs out.
var i = 3;
function message(){
console.log("hey");
if (--i < 0) {
clearInterval(tmr);
}
}
var tmr = setInterval(message, 1000);
you have to assign that setInterval to a javascript variable to name it what for this setInterval, like this
var messageLog = setInterval(message, 1000);
After, in setInterval message function add this condition to clear the inverval whenever you want to clear.
function message(){
if(i>3) {
clearInterval(messageLog); // clearInterval is a javascript function to clear Intervals.
return null;
}
console.log("hey");
}
You can retrieve the timer when creating and clear it if needed.
var i=3;
var timer = setInterval(message,1000);
function message(){
console.log("hey");
iā€”-;
if(i==0)
clearInterval(timer)
}
a beginner here too,look for clearInterval method ...

Define a timer in JavaScript

I have a function in JavaScript. I use setInterval in order to control my function. I also have another logic for controlling my function. I have a counter which is increased once one condition happens and is decreased when another condition happens. Now, sometimes the second condition does not happen and hence my function won't be resume anymore. (I pause my function when my first condition happen). Therefore, I want to wait at most 30 seconds for the second condition. If it does not happen, then I want to resume my function anyway. I have following code, but it does not work as I expect it. What happens is that it resume my function every 30 seconds. Then, it may be resumed while it should wait. Can someone let me know what is the problem with my code?
Please note that, the value for the counter may increase to more than 20. I mean the first and second condition may occur more than once.
function main()
{
// body
}
function increaseCounter()
{
counter += 1;
clearInterval(controller);
controlSecond = setInterval(function(){
counterSeconds += 1;
if (counterSeconds == 30)
{
counterSeconds = 0;
controller = setInterval(main, 100);
clearInterval(controlSecond);
}
}, 1000);
}
function decreaseCounter()
{
counter -= 1;
if (counter == 0)
{
counterSeconds = 0;
clearInterval(controlSecond);
controller = setInterval(main, 100);
}
}
Consider what happens if you call increaseCounter twice in a row.
On the first execution it will create interval A and assign it to controlSecond.
On the second execution it will create interval B and assign it to controlSecond, while interval A continues to fire off indefinitely. You won't stop it with clearInterval(controlSecond) because controlSecond no longer references interval A.
The problem is that you continue to set controlSecond and controller to a new interval without clearing them first. That results in the intervals being leaked with no way of clearing them. It's sort of like a memory leak where you have dynamically allocated memory but nothing pointed at it, but instead of renegade memory you have renegade intervals.
One way to prevent this is to make sure you always clear your interval before setting it.
I would also recommend that you implement controlSecond with a setTimeout because that is designed for tasks which only happen once.
Why not
var counter = 0
var timeout = null
function main () {
clearTimeout(timeout);
timeout = null;
}
function increaseCounter () {
counter++;
if (!timeout)
timeout = setTimeout(main, 30*1000);
}
function decreaseCounter() {
counter--;
if (counter === 0)
main();
}

How to clear interval in recursive call in javascript

I am using setInterval(); function to run a function every 5 sec, but i want to clear this interval if
some condition satisfied.
function do_the_job(){
//some code
if(some_condition)
{
clearInterval(interval);
}else{
clearInterval(interval);
var interval = setInterval(do_the_job(),5000);
}
}
function clearInterval(); is not working here.
In your code the var interval =... is local, not visible outside the scope of the function call, and thus will not work in a recursive function.
Make the interval a global variable, and it will work.
solution
var interval;
function do_the_job(){
//some code
if(some_condition)
{
clearInterval(interval);
}else{
clearInterval(interval);
interval = setInterval(do_the_job(),5000);
}
}
Make interval a global or 'higher scoped' variable by moving its declaration outside the if statements, so that it's actually in scope when clearing.
This is not a good time to use setInterval(), try setTimeout() instead
function do_the_job(){
//some code
if(some_condition)
{
// job done
}else{
setTimeout(do_the_job,5000);
}
}
var interval = setInterval(do_the_job(),5000);
Should be no parethesees
var interval = setInterval(do_the_job,5000);

clearTimeout in closures

I have created a jquery plugin with following structure:
(function($){
var timer_handle, i = 5 ;
$.my_plugin = function(){
return{
// provide $.my_plugin.reset() public method to reset
reset : function(){ clearTimeout(timer_handle); }
}
}();
$.fn.my_plugin = function(){
// init codes ...
function tick(){
i -= 1;
console.log(i+'sec elapsed');
if(i == 0){
console.log('time over');
$.my_plugin.reset();
}
timer_handle = setTimeout(tick, 1000);
}
tick();
}
})(jQuery);
$('body').my_plugin();
When I see at console , after 0 sec elapsed, the counter is still running in negative,
ie the setTimeout has not been cleared.
As I examined , the public method
$.my_plugin.reset(); called from outside clear the timer,
but $.my_plugin.reset() called inside tick closure do not clear timer.
What may be the solution for such case ?????
Because you're calling $.my_plugin.reset(); from inside the tick() function there is no timeout to clear. The previously scheduled timeout has already happened and that's why tick() is executing. (This has nothing to do with whether the code is in a closure or not.)
Instead, just don't set the next timeout if i has reached 0:
function tick(){
i -= 1;
console.log(i+'sec elapsed');
if(i == 0){
console.log('time over');
} else {
timer_handle = setTimeout(tick, 1000);
}
}
If you were to call $.my_plugin.reset(); from some other code outside tick() then there would be an outstanding timeout that could be cleared so it would stop tick() running again.
Note that declaring your timer_handle and i variables in that immediately invoked anonymous function means that all calls to your plugin will access those same variables so you will get incorrect behaviour if you run your plugin against more than one element on the page at the same time.

clearTimeout() doesn't do what it's supposed to do

can anyone see what is wrong with the following code. it's supposed to display a count down from 30 and afterwards it refreshes the page with jquery's ajax load() function.
it works fine for the first or second count down but then the timer starts too count down to fastand sometimes goes to the negative numbers and does not stop at all
what am i doing wrong?
function refreshPage(){
stopRefresh();
$('div.yui-content').load('rdPage.aspx div.yui-content', doCalculation);
}
function stopRefresh(){
clearTimeout(timer);
clearTimeout(interval);
}
var count, timer, interval;
function startTimer(){
count = 30;
timer = setTimeout(refreshPage,count * 1000);
interval= setInterval(updateTimer,1000);
}
function updateTimer(){
count --;
$('#timerSpan').text("Refreshing in " + count + "s");
}
function doCalculation(){
negativeNumberRed();
startTimer();
}
edit: added doCalculations()
try
clearInterval(interval); instead of clearTimeout(interval);
Like this:
function stopRefresh(){
clearTimeout(timer);
clearInterval(interval);
}
Add a call to "stopRefresh()" to the "startTimer()" call.
function startTimer(){
stopRefresh();
count = 30;
timer = setTimeout(refreshPage,count * 1000);
interval= setInterval(updateTimer,1000);
}
My guess is that your code is managing to start up more than one instance of the interval timer. They'll all decrement the same counter.
edit ā€” oops - Dr. Strangelove is correct - you need to use "clearInterval()" on interval timers, and "clearTimeout()" for timeout timers. (edit again well, you probably should do that, but Chrome at least seems to stop interval timers via "clearTimeout()". Here is the jsfiddle.
I think it's better to only use the interval..
And when the count < 1 call refreshPage

Categories

Resources