I want to set timer every 5th minute. Example: timer countdown 5 minutes only at time 00:00 , 00:05 , 00:10 , 00:15 etc. in 00:17 timer should countdown 3 minutes
how setTimeout and setInterval with that provision?
I would like to do it programmatically, in React JS using javascript, anyone can help me?
When you want a function to run at a specific clock time, like every full minute, it's usually best to use setTimeout with sequential calls. That way you can work out the time to the next whole "tick" and set the timeout for that interval. This stops small lags caused by the system being busy accumulating, making the timing drift.
Using setInterval lags accumulate so the timing slowly drifts. The first run needs setTimeout anyway to start it at the right time (e.g. next full tick).
Here's a simple example to run a function on whatever tick you want, specified in milliseconds. The example is every 30 second tick but if you want 5 minutes just call it with 3e5 (i.e. 5 * 60 * 1000 = 300,000 which is the number of milliseconds in 5 minutes). Then it will run at the next full tick and every tick after that until cancelled.
setTimeout also returns an identifier (timer id, not used in the example) that you can use to stop it if necessary.
/**
* Run a function on every tick at specified interval. First
* call of fn is on next tick. May be a few ms late depending
* on system load when fn due to run.
*
* #param {Function} fn - function to call
* #param {number} tick - clock tick to run function on in milliseconds
* e.g. 30 secs = 3e4, 1 min = 6e4, 5 min = 3e5
*/
function onEveryTick(fn, tick) {
// Time to next tick
let getTick = () => tick - (Date.now() % tick);
// Currie function to sequentially call itself
let f = () => {
fn();
setTimeout(f, getTick());
}
// First call after required lag
setTimeout(f, getTick());
}
// Call on 30 second tick
onEveryTick(() => console.log('Tick ' + new Date().toString()), 3e4);
Related
in order to run a same script multiple times, i currently use ;
For example, i will run something like this
node RocketLaunch.js;node RocketLaunch.js;node RocketLaunch.js
This works great and run my script 3 times back to back. I am wondering is there an easy way i can run these 3 with gap of 1 hour?
Edit - Thank you for the responses, i am new to learning programming so apologize for posting this in JS, since it seems like a non JS question.
More information - The way i want to intend to use it, run this script every 1 hour for lets say 20 hours/times. The entire job takes around 5 minutes after i run the script and i want it to run every hour and do that 5 minutes job.
So perhaps run a command at Bash level, where i can type it 20 times with a delay of an hour. It runs every hour for 20 hours, then i can do the whole thing again.
This is how I typically do this in bash:
for x in {1..3};
do
node RocketLaunch.js
sleep 3600
done
The {1..3} tells the for loop to do this 3 times, and the sleep function takes the number of seconds as its argument. (3600 = 60 seconds * 60 minutes)
Here is the updated answer to your question
Now just run node RocketLaunch.js 1 20 This is the command to tell the script to run every 1 hour for the next 20 hours.
const rockets = {
launched: () => {
//your job
console.log("I'm A Rocket");
}
};
var arg = process.argv;
const times = Number(arg.slice(2)[1]);
const hours = Number(arg.slice(2)[0]) * 3600000; // to make the hour;
function launch() {
var x = 1
//kick off rockets at script start
rockets.launched();
timer = setInterval(() => {
rockets.launched();
x++
if (x === times) {
clearInterval(timer);
}
}, hours) //1000 ms = 1 second
}
launch();
I have a create-react-app that has a setInterval that runs a tick() function every 1000 millisecond. The tick() function decrements the sessionTime state by one. It works perfectly fine when the browser tab is in the foreground but it loses count in the background (not counting after a certain period). How do I allow it to continue running? Is this even the right approach to a timer in React?
You might be running out of your time budget?
Anyway, a more reliable way is not to rely on the interval being a specific time; check current new Date() every time you execute your tick, calculate how much time has passed since last tick or since a certain remembered start time (or remaining to certain target time), and act accordingly.
For example, if you want a session to expire in 30 minutes,
let now = new Date();
const second = 1000;
const minute = 30 * second;
let expiryTime = new Date(now.getTime() + 30 * minute);
and then in your tick just check whether new Date() > expiryTime. This way, it does not matter how often your tick routine runs.
I work on CodeHS and need to make a countdown timer for my powerups in the game I'm making, Breakout. I need the timer to be reusable so no for loops, it needs to go down in seconds/milliseconds (it doesn't matter which) and preferably last 30 seconds or 30,000 milliseconds. Remember this is CodeHS I'm working on.
If you want something to happen 30 seconds after you start your timer you could do something like this:
//set the time remaining to 30 outside of a function so it is global
var timeRemaining = 30;
function start(){
//set the timer to run the function countdown once every second(1000 milliseconds)
setTimer(countdown, 1000)
}
function countdown(){
/*every time it is called this function subtracts one from the time if it is
more than 30, when it reaches 0 stops the timer and resets the time*/
if(timeRemaining<=0){
stopTimer(countdown);
timeRemaining = 30;
println("Done");
//30 seconds has passed, do what you need here(call your function)
}else{
timeRemaining--;
println(timeRemaining+" seconds left")
}
}
Add your function or whatever you want to happen after the time is up whereprintln("Done") is.
Because timeRemaining is set back to 30 at the end, you can reuse the timer by calling setTimer(countdown, 1000) again.
You can remove the println statments, they are just to see what is happening.
If CodeHS doesn't want hardcoded numbers (I think they call them "magic numbers"), replace the 30s with a constant set to 30.
Let me know if you need a better explanation.
Tell me if I'm wrong because I have no idea what CodeHS is, but I am quite sure that this can be achieved with a simple setInterval function.
To go by full seconds:
var timer=30;
setInterval(function(){
timer-=1;
document.getElementById(timerId). innerHTML=timer;//shows the remaining time
}, 1000);//subtracts 1 second from timer each second
To go by tenths of a second
var timer=30.0;
setInterval(function(){
timer-=0.1;
document.getElementById(timerId). innerHTML=timer;//shows the remaining time
}, 1000);//subtracts a tenth second from timer every 0.1 seconds
var timeLeft = 60;
var txt = new Text(" ","30pt Arial");
function start(){txt.setPosition(200,200); txt.setColor(Color.black); add(txt); setTimer(countdown,1000);}
function countdown(){drawTimer(); timeLeft--;}
function drawTimer(){txt.setText(timeLeft);}
So I've got this JavaScript clock I'm working on and I want it to be perfectly synced with the clients' system clock. I know how to get the current time using a Date object and I know how to run the update function every 60000 milliseconds (1 minute). The thing is that the client might load the page when half a minute has already passed, making the clock lag behind with 30 seconds. Is there any way to just run the update function when the minute-variable actually changes? (I only want minute-precision.)
How I get the current time:
var time = new Date();
var currentHour = time.getHours();
var currentMinute = time.getMinutes();
How I run the update function every 60000 ms:
setInterval(update,60000); //"update" is the function that is run
When the user logs in, get the current time and seconds of the minute, subtract 60 to get the remaining seconds, then multiply to set the timer
var time = new Date(),
secondsRemaining = (60 - time.getSeconds()) * 1000;
setTimeout(function() {
setInterval(update, 60000);
}, secondsRemaining);
First, you have to understand that timers in javascript are not guaranteed to be called on time so therefore you cannot be perfectly synced at all times - javascript just isn't a real-time language like that. It is single threaded so a timer event has to wait for other javascript that might be executing at the time to finish before a timer can be executed. So, you must have a design that still does as best as possible even if the timer is delayed (called later than it's supposed to be).
If you wanted to try to stay as close to aligned and do the fewest screen updates and be the most friendly to mobile battery life, I'd suggest this self-aligning code which realigns itself on each tick based on the time remaining until the next minute change:
function runClock() {
var now = new Date();
var timeToNextTick = (60 - now.getSeconds()) * 1000 - now.getMilliseconds();
setTimeout(function() {
update();
runClock();
}, timeToNextTick);
}
// display the initial clock
update();
// start the running clock display that will update right on the minute change
runClock();
This has the advantage that it only calls the update once on the next minute boundary.
Working demo: http://jsfiddle.net/jfriend00/u7Hc5/
var time = new Date();
var currentHour = time.getHours();
var currentMinute = time.getMinutes();
var currentSecond = time.getSeconds();
var updateinterval = setInterval(startTimer,(60-currentSecond)*1000);
function startTimer(){
clearInterval(updateinterval);
setInterval(update,60000);
}
function update(){
var time = new Date();
console.log(time.getSeconds());
}
I would set an interval to run each second, then check if time.getSeconds() == 0. This way you could execute an action whenever a new minute starts, based on the client time.
I'm building a gantt chart style timeline using html canvas element.
I am currently attempting to add the functionality which allows the user to click a next/prev button to have the gantt chart scroll to display earlier or later times.
The way I am doing this is to have a span.adjustTime where the id holds a value in seconds for the time to be adjusted (eg 86400 for one day).
I am trying to animate the scrolling so it looks like a scroll, rather than jumping ahead by one day.
I have a small problem in my timing calculation, but the script below is not animating, but rather jumping directly to the final time.
I do have the draw function running on a separate setInterval which updates every second, so I'm hoping it isn't an issue of conflicting timers on the same function on the same element and data.
jQuery('span.adjustTime').click(function() {
var adjustBy = parseInt(jQuery(this).attr('id').replace('a', ''));
var data = jQuery('img#logo').data();
for(var m = 1; m >= 30; m++) {
gantt.startUnixTime = gantt.startUnixTime + (adjustBy * (m * 0.001));
var moveTimer = setTimeout(function() {
draw(document.getElementById('gantt'), data, gantt);
}, 1000);
if (m == 30) {
clearTimeout(moveTimer);
}
}
});
In the for loop you are calling setTimeout 30 times, each time with the same timeout value of 1000. So after 1000 milliseconds 30 scheduled functions will execute at almost the same time. I suppose this is not what you intended. If you wanted an animation of 30 frames over 1000 milliseconds, the setTimeout should look something like:
setTimeout(function() { ... }, 1000 / 30 * m)
Also note that all 30 scheduled functions will see the same gantt.startUnixTime value, since the same object (gantt) is passed to all of them, and when they execute, the for loop has finished already long ago.