Simple question here that I can't seem to find an answer for: Once a setTimeout is set, is there any way to see if it's still, well, set?
if (!Timer)
{
Timer = setTimeout(DoThis,60000);
}
From what I can tell, when you clearTimeout, the variable remains at its last value. A console.log I just looked at shows Timer as being '12', no matter if the timeout has been set or cleared. Do I have to null out the variable as well, or use some other variable as a boolean saying, yes, I have set this timer? Surely there's a way to just check to see if the timeout is still running... right? I don't need to know how long is left, just if it's still running.
What I do is:
var timer = null;
if (timer != null) {
window.clearTimeout(timer);
timer = null;
}
else {
timer = window.setTimeout(yourFunction, 0);
}
There isn't anyway to interact with the timer except to start it or stop it. I typically null the timer variable in the timeout handler rather than use a flag to indicate that the timer isn't running. There's a nice description on W3Schools about how the timer works. In their example they use a flag variable.
The value you are seeing is a handle to the current timer, which is used when you clear (stop) it.
There is no need to check for an existing timer, just execute clearTimeout before starting the timer.
var timer;
//..
var startTimer = function() {
clearTimeout(timer);
timer = setTimeout(DoThis, 6000);
}
This will clear any timer before starting a new instance.
Set another variable Timer_Started = true with your timer. And also change the variable to false when the timer function is called:
// set 'Timer_Started' when you setTimeout
var Timer_Started = true;
var Timer = setTimeout(DoThis,60000);
function DoThis(){
// function DoThis actions
//note that timer is done.
Timer_Started = false;
}
function Check_If_My_Timer_Is_Done(){
if(Timer_Started){
alert("The timer must still be running.");
}else{
alert("The timer is DONE.");
}
}
I know this is a necroposting but i think still people are looking for this.
This is what i use:
3 variables:
t for milliseconds since.. in Date Object for next target
timerSys for the actual interval
seconds threshold for milliseconds has been set
next i have a function timer with 1 variable the function checks if variable is truly, if so he check if timer is already running and if this is the case than fills the global vars , if not truly, falsely, clears the interval and set global var timerSys to false;
var t, timerSys, seconds;
function timer(s) {
if (s && typeof s === "number") {
if (typeof timerSys === "boolean" || typeof timerSys === "undefined") {
timerSys = setInterval(function() {
sys();
}, s);
t = new Date().setMilliseconds(s);
seconds = s;
}
} else {
clearInterval(timerSys);
timerSys = false;
}
return ((!timerSys) ? "0" : t)
}
function sys() {
t = new Date().setMilliseconds(seconds);
}
Example I
Now you can add a line to sys function:
function sys() {
t = new Date().setMilliseconds(seconds);
console.log("Next execution: " + new Date(t));
//this is also the place where you put functions & code needed to happen when interval is triggerd
}
And execute :
timer(5000);
Every 5 seconds in console:
//output:: Next execution: Sun May 08 2016 11:01:05 GMT+0200 (Romance (zomertijd))
Example II
function sys() {
t = new Date().setMilliseconds(seconds);
console.log("Next execution: " + seconds/1000 + " seconds");
}
$(function() {
timer(5000);
});
Every 5 seconds in console:
//output:: Next execution: 5 seconds
Example III
var t, timerSys, seconds;
function timer(s) {
if (s && typeof s === "number") {
if (typeof timerSys === "boolean" || typeof timerSys === "undefined") {
timerSys = setInterval(function() {
sys();
}, s);
t = new Date().setMilliseconds(s);
seconds = s;
}
} else {
clearInterval(timerSys);
timerSys = false;
}
return ((!timerSys) ? "0" : t)
}
function sys() {
t = new Date().setMilliseconds(seconds);
console.log("Next execution: " + seconds / 1000 + " seconds");
}
$(function() {
timer(5000);
$("button").on("click", function() {
$("span").text(t - new Date());
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Freebeer</button>
<span></span>
Note this way you can go below 0
I usually nullify the timer:
var alarm = setTimeout(wakeUpOneHourLater, 3600000);
function wakeUpOneHourLater() {
alarm = null; //stop alarm after sleeping for exactly one hour
}
//...
if (!alarm) {
console.log('Oops, waked up too early...Zzz...');
}
else {
console.log('Slept for at least one hour!');
}
Related
So like the title says i have this timer and i would like that once that it reaches 0, it should check if a variable called "user_energy" in this case is equal to 100. If it is than the timer will stop, and it could do something. Like for example just a console.log("It works") and if its not then it should repeat itselfs.
How would you be able to do something like that?
This is the code:
function startTimer() {
var interval = 10000;
{
localStorage.endTime = +new Date + interval;
}
if(!localStorage.endTime)
{
startTimer();
}
setInterval(function()
{
var remaining = localStorage.endTime - new Date;
if( remaining >= 0 )
{
$('#energytimer').text( Math.floor( remaining / 1000 ) );
} else
{
startTimer();
}
}, 100);
}
It's a little unclear how the localStorage stuff fits into the question, but here's a simple countdown timer that does what you are asking. You can adapt this to store the counter in localStorage if that's what you want to do.
The key is to assign a variable to the return value from the timer so that you can call clearTimeout() and pass that variable and stop the timer later.
let timer = null; // <-- This will hold a reference to the timer
var counter = 5;
timer = setInterval(function(){
if(counter === 0){
clearTimeout(timer); // Stop the timer
console.log("Times up!");
} else {
$("#energytimer").text(counter--);
}
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="energytimer"></div>
I was planning to get a data from the server every minute. However, if I run this code, this function is being called repeatedly. On the other hand, if I added date.getMilliseconds == 0 in the condition, it won't process any results.
Do you have any suggestions on how to run the function once every 1 minute?
async update() {
var date = new Date();
if (date.getSeconds() == 0) {
var newdata = await getData(1);
array.shift();
array.push(newdata);
}
}
Since it looks like you don't have fine control over when update is called, one option would be to set a boolean to true every time getSeconds() === 0 (set it to false otherwise), and then only run the real code when the flag is false and getSeconds() === 0:
let hasRun = false;
// ...
async update() {
var date = new Date();
const secs = date.getSeconds();
if (secs !== 0) {
hasRun = false;
} else if (secs === 0 && hasRun === false) {
hasRun = true;
// your code
var newdata = await getData(1);
array.shift();
array.push(newdata);
}
}
An alternative that might require less resources due to not creating Dates every frame would be to have a separate function that toggles the boolean, set with a setInterval that runs every 60 seconds, no Dates involved:
let hasRun = false;
setInterval(() => hasRun = false, 60000);
async update() {
if (hasRun) return;
hasRun = true;
// your code
}
(of course, you could also try setInterval(update, 60000) if the framework allows it)
I'm trying to make a jQuery countdown type animation, that once it hits 0 it executes a function. However I'm having problems because I'm unsure how to go about doing this. I thought I'd do a while loop then pause for a second until it hits 0. However it doesn't seem possible to pause a while loop. So I'm wondering what's the best way to do this? Thanks.
countdown takes an HTMLElement to display itself and the number of seconds to count down for
It returns a Promise that resolves when the counter reaches 0
We can use a .then call to apply a function when the count-down has completed
function countdown(elem, s) {
return new Promise(function(resolve) {
function loop(s) {
elem.innerHTML = s
if (s === 0)
resolve(elem)
else
setTimeout(loop, 1000, s - 1)
}
loop(s)
})
}
countdown(document.querySelector('#a'), 3).then(
function(elem) { console.log('done', elem) }
)
countdown(document.querySelector('#b'), 5).then(
function(elem) { console.log('done', elem) }
)
countdown(document.querySelector('#c'), 10).then(
function(elem) { console.log('done', elem) }
)
<p id="a"></p>
<p id="b"></p>
<p id="c"></p>
You should also be aware that setTimeout and setInterval do not guarantee that the milliseconds argument used is 100% accurate …
var last = Date.now()
var interval = setInterval(function() {
var now = Date.now()
var delta = now - last
console.log(delta)
last = now
}, 1000)
setTimeout(clearInterval, 10000, interval)
// 1000
// 1003
// 998
// 1002
// 999
// 1007
// 1001
// ...
If you need a long running timer with high accuracy, I recommend you adapt the solution to use delta-based updates to the clock. If you rely upon setTimeout or setInterval for accuracy, you will be sad.
function countdown(elem, ms) {
return new Promise(function(resolve) {
function loop(ms, last) {
let now = Date.now()
let delta = now - last
if (ms <= 0) {
elem.innerHTML = 0
resolve(elem)
}
else {
elem.innerHTML = (ms/1000).toFixed(3)
setTimeout(loop, 25, ms - delta, now)
}
}
loop(ms, Date.now())
})
}
countdown(document.querySelector('#a'), 3000).then(
function(elem) { console.log('done', elem) }
)
countdown(document.querySelector('#b'), 5000).then(
function(elem) { console.log('done', elem) }
)
countdown(document.querySelector('#c'), 10000).then(
function(elem) { console.log('done', elem) }
)
<p id="a"></p>
<p id="b"></p>
<p id="c"></p>
Code:
var counter = 10;
var yourFunc = function(){}
var interval = setInterval(function(){
counter--;
if(counter <=0){ yourFunc(); clearInterval(interval); }
}, 1000);
I would use a recursive function
var countDown = function(secondsRemaining){
secondsRemaining -= 1;
if(secondsRemaining <= 0){
//execute
} else {
//wait 1 second and call again
setTimeout(function(){
countDown(secondsRemaining);
}, 1000);
}
}
then to initially start countdown (5 seconds)
countDown(5000);
I would use something like the following :
$(document).ready(function(){
var counter=10;
countDown();
function countDown(){
$('#showNumber').text(counter--);
if(counter>=0)
window.setTimeout(countDown,1000)
else
otherFunction();
}
function otherFunction(){
$('#showNumber').text('FINISHED!');
}
});
Try this out. It does not require jQuery.
var count = 5; // Number of times to run 'counter_function'.
// Run 'counter_function' every second (1000ms = 1 second)
var counter = setInterval(function(){
counter_function()
}, 1000);
// The function to run when 'count' hits 0.
var done_function = function() {
console.log('done');
}
// The function to run at each interval.
var counter_function = function() {
console.log('count');
count--;
if(count === 0){
done_function();
clearInterval(counter);
}
}
It will print the word 'count' every second for 5 seconds, and at the last second it will also print 'done'.
Are you looking for something like this OP?
This executes every second. You can use clearInterval() just as I added in the comment section whenever you want it to stop.
var start = 10; // time to countdown from in seconds
var interval = setInterval(
function(){
if (start == 0) {
complete();
clearInterval(interval);
}
$(".update").html("<h4>Countdown "+start+"</h4>");
start--;
}, 1000);
function complete() {
console.log("called the callback, value of start is: "+start);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="update">
</div>
<div id="counter">1:00</div>
function countdown() {
var secs = 60;
function tick() {
var counter = document.getElementById("counter");
secs--;
counter.innerHTML = "0:" + (secs < 10 ? "0" : "") + String(secs);
if( secs > 0 ) {
setTimeout(tick, 1000);
} else {
alert("Game Over");
}
}
tick();
}
countdown(60);
I am having a problem with this portion of my game. I'm trying to set a 60 seconds timer for the game that starts at 60 and ends at 0, when it gets to 0 the game stops and an alert shows that the game is over.
I am very new to programming, so please give me as many feedbacks as you can. I found this code on the internet, and I figured out most of it, could you also tell me what does the tick() function do over here?
Here is one way you can do it:
First declare a variable you will use for an interval (should be 'global', attached to window):
var countDownInterval = null;
Then, a function to trigger the tick interval, you should call this whenever the game is ready to start:
function startCountDown()
{
countDownInterval = setInterval(tick,1000); //sets an interval with a pointer to the tick function, called every 1000ms
}
which will call the tick function every second:
function tick()
{
// Check to see if the counter has been initialized
if ( typeof countDownInterval.counter == 'undefined' )
{
// It has not... perform the initialization
countDownInterval.counter = 0; //or 60 and countdown to 0
}
else
{
countDownInterval.counter++; //or --
}
console.log(countDownInterval.counter); //You can always check out your count # the log console.
//Update your html/css/images/anything you need to do, e.g. show the count.
if(60<= countDownInterval.counter) //if limit has been reached
{
stopGame(); //function which will clear the interval and do whatever else you need to do.
}
}
and then the function where you can do everything you need to do after game has finished:
function stopGame()
{
clearInterval(countDownInterval);//Stops the interval
//Then do anything else you want to do, call game over functions, etc.
}
You can fire up the counter at any time by calling startCountDown();
Pseudo code of tick:
function tick() {
reduce counter variable;
if counter > 0
wait for 1 second; (This is what setTimeout(tick, 1000) means)
call tick() again (recursively)
}
else {
game over
}
}
Something like this?
var countdown = function(sec, tick, done) {
var interval = setInterval(function(){
if(sec <= 0) {
clearInterval(interval);
done();
} else {
tick(sec)
sec--;
}
}, 1000)
}
countdown(10, console.log, function(){console.log('done')})
This question already has answers here:
Changing the interval of SetInterval while it's running
(17 answers)
Closed 9 years ago.
Here is an example situation.
var count,
time = 1000;
setInterval(function(){
count += 1;
}, time);
The code above will add 1 to the "count" var, very 1000 milliseconds.
It seems that setInterval, when triggered, will use the time it sees on execution.
If that value is later updated it will not take this into account and will continue to fire with the initial time that was set.
How can I dynamically change the time for this Method?
Use setTimeout instead with a callback and a variable instead of number.
function timeout() {
setTimeout(function () {
count += 1;
console.log(count);
timeout();
}, time);
};
timeout();
Demo here
Shorter version would be:
function periodicall() {
count++;
setTimeout(periodicall, time);
};
periodicall();
Try:
var count,
time = 1000,
intId;
function invoke(){
intId = setInterval(function(){
count += 1;
if(...) // now i need to change my time
{
time = 2000; //some new value
intId = window.clearInterval(intId);
invoke();
}
}, time);
}
invoke();
You cannot change the interval dynamically because it is set once and then you dont rerun the setInterval code again. So what you can do it to clear the interval and again set it to run. You can also use setTimeout with similar logic, but using setTimeout you need to register a timeout everytime and you don't need to possibly use clearTimeout unless you want to abort in between. If you are changing time everytime then setTimeout makes more sense.
var count,
time = 1000;
function invoke() {
count += 1;
time += 1000; //some new value
console.log('displ');
window.setTimeout(invoke, time);
}
window.setTimeout(invoke, time);
You cant (as far as i know) change the interval dynamically. I would suggesst to do this with callbacks:
var _time = 1000,
_out,
_count = 0,
yourfunc = function() {
count++;
if (count > 10) {
// stop
clearTimeout(_out); // optional
}
else {
// your code
_time = 1000 + count; // for instance
_out = setTimeout(function() {
yourfunc();
}, _time);
}
};
integers are not passed by reference in JavaScript meaning there is no way to change the interval by changing your variable.
Simply cancel the setInterval and restart it again with the new time.
Example can be found here:
http://jsfiddle.net/Elak/yUxmw/2/
var Interval;
(function () {
var createInterval = function (callback, time) {
return setInterval(callback, time);
}
Interval = function (callback, time) {
this.callback = callback;
this.interval = createInterval(callback, time);
};
Interval.prototype.updateTimer = function (time) {
clearInterval(this.interval);
createInterval(this.callback, time);
};
})();
$(document).ready(function () {
var inter = new Interval(function () {
$("#out").append("<li>" + new Date().toString() + "</li>");
}, 1000);
setTimeout(function () {
inter.updateTimer(500);
}, 2000);
});