javascript stopping a repeating setTimeout function [duplicate] - javascript

This question already has answers here:
Cancel/kill window.setTimeout() before it happens
(2 answers)
Closed 7 years ago.
I have a function that functions as a countdown timer for a simple pomodoro clock I'm building. Now I want to stop this function when the user clicks a reset function. I though I'd pass it a simple if statement that returns something and therefore terminates the function before the countdown iterates again but the function keeps on going. Any idea what's going on here is appreciated. Code below, can also check the whole thing on codepen.
function countdown(blocker) {
if (blocker === true) {
return true;
}
else {
setTimeout(function() {
time -= 1;
updateTimer();
if (time > 0) {
countdown();
}
}, 1000);
}
}
calling the function like this doesn't stop it once it gets going:
countdown(true);

Don't need to use setInterval, as suggested by K Ф, But you do need to clear the timeout with clearTimeout. Make sure you store a reference to your timeout object:
timeout = setTimeout(/* arguments */);
And add a reset function and use it when resetting:
function reset () {
if(timeout)
clearTimeout(timeout);
time = 1500;
}
Here's your Pen updated.

Use setInterval with clearInterval.
var si = -1;
var countdown = function() {
si = setInterval(function() {
time -= 1;
updateTimer();
if (time <= 0) {
clearInterval(si);
}
}, 1000);
};
//Where button is the reference to a button existing in your html page
button.onclick = function() {
clearInterval(si);
//reset info here
timer = 2000;
countdown();
}

Related

Timer shows wrong results

var seconds_lapsed = 0;
function tick() {
seconds_lapsed++;
}
function countup() {
setTimeout(function () {
if (stopped) return; // stop the loop
if (!is_paused()) {
tick();
show_time_left();
}
countup(); // <--- this is the "loop"
}, 1000);
}
This is the core of my timer. Of course I have some view to represent the result. But ticking is done here.
The problem
It shows wrong time. Have a look at this:
The timer was set for 3 hours. Twelve minutes lapsed. And the discrepancy is almost 1.5 minutes.
In the other window the timer by Google is working. This one:
So, I just compared my timer with that of google. I started them almost at once. The difference should be no more than a couple of seconds (to switch the window and press the button).
What is the reason for this, and how can I correct it?
setTimeout with an interval of 1000 does NOT run exactly after every 1 seconds.
It schedules to run after 1 second, but can be delayed with by actions running at that time.
A better way of solving this is by calculating via date difference.
I took your sample (added the missing vars/funcs) and changed the tick() function to use date diffs.
var seconds_lapsed = 0;
var startDateTime = new Date();
var stopped = false;
var is_paused = function() { return false; }
function tick() {
datediffInms = new Date() - startDateTime;
seconds_lapsed = Math.round(datediffInms / 1000);
}
function countup() {
setTimeout(function () {
if (stopped) return; // stop the loop
if (!is_paused()) {
tick();
//show_time_left();
console.log(seconds_lapsed)
}
countup(); // <--- this is the "loop"
}, 1000);
}
countup();

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 ...

Wait until variable equals

I am trying to check if a variable is equal to 1 using javascript...
myvalue = 1;
function check() {
if (myvalue == 1) {
return setTimeout(check, 1000);
}
alert("Value Is Set");
}
check();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I am planning on adding a delay to the setting of the variable but for now why is this simple version not working?
Using setTimeout(check, 1000); calls the function only once. That's not what you are looking for.
What you're looking for is setInterval which executes a function every n miliseconds.
Look at the below example which waits for the value to be 1, using setInterval, and then clearing the setInterval instance once it does.
Wait 4 seconds when running the snippet below:
// First - set the value to 0
myvalue = 0;
// This variable will hold the setInterval's instance, so we can clear it later on
var interval;
function check() {
if (myvalue == 1) {
alert("Value Is Set");
// We don't need to interval the check function anymore,
// clearInterval will stop its periodical execution.
clearInterval(interval);
}
}
// Create an instance of the check function interval
interval = setInterval(check, 1000);
// Update the value to 1 after 4 seconds
setTimeout(function() { myvalue = 1 }, 4000);

recursive setTimeout - not a variable

I want to make a timer that counts down from some initial number and stops when it gets to zero.
I originally did this with setInterval, but I wanted to separate the timer (setInterval) from the count down function, and was finding it difficult to terminate the setInterval.
I'm currently trying to achieve the same thing with a setTimeout which conditionally calls the same setTimeout again, but it doesn't work.
function Timer(initialTime) {
this.time = initialTime;
this.tickTock = null
}
Timer.prototype.countDown = function() {
if (this.time <= 0) {
clearTimeout(this.tickTock);
} else {
console.log(this.time);
this.time--;
this.proceed();
}
}
Timer.prototype.proceed = function() {
this.tickTock = setTimeout(this.countDown, 3000);
}
var timer = new Timer(10);
timer.proceed();
When calling timer.proceed(), I'm getting error:
TypeError: this.proceed is not a function
at Timer.countDown [as _onTimeout]
How can I refer to the proceed function from within the countDown function?
The callback to setTimeout is not bound to your object but it's bound to window thus this is the window objet not your timer object. You can bind the callback using Function.prototype.bind like this:
this.tickTock = setTimeout(this.countDown.bind(this), 3000);
Note: when using setTimeout there will be no need for this.tickTock, you can stop the counting down by not calling another proceed. You can keep it but it will be of no use. (see the code snippet bellow).
Working code snippet:
function Timer(initialTime) {
this.time = initialTime;
}
Timer.prototype.countDown = function() {
if (this.time <= 0) { // if the counter is less or equal 0, return and don't call proceed
return;
}
// otherwise continue
console.log(this.time);
this.time--;
this.proceed();
}
Timer.prototype.proceed = function() {
setTimeout(this.countDown.bind(this), 1000);
}
var timer = new Timer(10);
timer.proceed();

Greasemonkey delay... setTimeout doesnt work ok

I've been playing around with a site, in which I want to continue clicking a button for i amount of times every interval seconds.
My code is:
clickbidBtn1 = function() {
var bidBtn=document.getElementById("BidButton");
var interval = 15000;
for (var i=3; i>=0; i--){
setTimeout(bidBtn.click(1);,i*interval);
};
I've found out that GM executes all i amount of clicks at the same time, not with the intended delay. is there a way to delay the time of click? Say i wanted the function to click the button every 15 second for i amount of times.
I was thinking of giving it some more variables, and adding one variable in the settimeout code part, which only executes # the click, then comparing increased variables with current ones before going to the next settimeout... but haven't thought it through yet... it seems to be a complicated process for a simple process... :( i wll play around with it a bit
Use setInterval() for this.
One way:
var bidClickTimer = 0;
var numBidClicks = 0;
function clickbidBtn1 ()
{
var interval = 15000;
bidClickTimer = setInterval (function() {BidClick (); }, interval);
}
function BidClick ()
{
numBidClicks++;
if (numBidClicks > 3)
{
clearInterval (bidClickTimer);
bidClickTimer = "";
}
else
{
bidBtn.click (1);
}
}
clickbidBtn1 ();
Alternatively, without using global vars:
function clickbidBtn1 ()
{
var interval = 15000;
this.numBidClicks = 0;
this.bidClickTimer = 0;
this.BidClick = function () {
numBidClicks++;
if (numBidClicks > 3)
{
clearInterval (bidClickTimer);
bidClickTimer = "";
}
else
{
bidBtn.click (1);
}
};
this.bidClickTimer = setInterval (function(thisScope) {thisScope.BidClick (); }, interval, this);
}
clickbidBtn1 ();
Just to explain why your code does not work: You are calling the .click method immediately (putting () after a function name calls the function) and actually passing the return value of that function to setTimeout. The for loop is so fast that everything seem to happen at the same time.
You have to pass a function reference to setTimeout, e.g. an anonymous function:
setTimeout(function() {
bidBtn.click(1);
}, i*interval);

Categories

Resources