Javascript timer updates to slow after resuming app - javascript

I have a simple stopwatch timer included in my Ionic app (Android). I basically just save the start date, and then check every second (mytimeout = $timeout($scope.onTimeout, 1000);) how many seconds it's been since that time. This works fine, but whenever I press the home button and then reopen the app (resume), it shows the old time for a fraction of a second, before updating to the new time. This does't happen when you exit the app and reopen it, because then it just calculates the new time.
Anyone who can help me with this? Any help is appreciated.
Update: countdown code:
$scope.onTimeout = function() {
$scope.clock=Math.trunc(timeleft());
mytimeout = $timeout($scope.onTimeout, 1000);
};
//timer counts down from 60 seconds
function timeleft()
{
var currentdate = new Date();
var currentdateseconds = currentdate.getTime()/1000;
var timeleft = 60 - (currentdateseconds - window.localStorage['seconds']);
return timeleft;
}

Related

Double interval call and it should not be in node.js

I have problem on server side (node.js) with setInterval.
I want to check something every day at specific time and I set interval like this:
let maintainTime = backFunc.getNextMaintainTime(new Date());
let maintain = setInterval(() => {
let currentTime = new Date();
if (currentTime.getTime() > maintainTime.getTime()) {
maintainTime = backFunc.getNextMaintainTime(maintainTime);
//do the maintain
}
}, 360000);
//360000 to check on every hour
and here is my getNextMaintainTime function:
getNextMaintainTime: (maintainTime) => {
maintainTime.setDate(maintainTime.getDate() + 1);
maintainTime.setHours(4);
maintainTime.setMinutes(0);
maintainTime.setSeconds(0);
maintainTime.setMilliseconds(0);
return maintainTime;
}
When I test it out it works perfectly but when I start server on production every time it calls this function 2 times instead of 1 time at 4am, what could cause the problem?

How can I get the timer started from the user input NOT the just constant value and keep my session storage still working?

I made a timer going even after reloading the page using javascript's session storage.
BUT regarding the timer at the first place, I want to get it started from getting USER INPUT.
Instead of specific number of time like 300(what I did so far below), I want to get a value from the user. Like, when the user clicked on a button on the page a pop up shows up asking the user how much time you want to put for the timer and the user put the value whatever he/she wants and the timer gets started upon that.
var userTime1 = 300;
var time = sessionStorage.getItem('timer_time');
var min = sessionStorage.getItem('timer_min');
var sec = sessionStorage.getItem('timer_sec');
if (!time){
time = userTime1;
min = parseInt(time/60);
sec = time%60;
}
var interval = setInterval(function () {
time--;
min = parseInt(time/60);
sec = time%60;
sessionStorage.setItem('timer_time', time);
sessionStorage.setItem('timer_min', min);
sessionStorage.setItem('timer_sec', sec);
document.getElementById("timeLeft1").innerHTML = min + "min" + sec + "sec";
};
if (time == 0) {
clearInterval(interval);
sessionStorage.removeItem('timer_time');
sessionStorage.removeItem('timer_min');
sessionStorage.removeItem('timer_sec');
sessionStorage.clear();
alert("Timer Expired!");
}
}, 1000);

Start interval when the next minute starts

In an agenda/calendar app I'm working on, I display a line to indicate the current time. I want to update the position of this line every minute.
If I start a setInterval function when the calendar component did mount or will mount, there is a change that it starts at the 59th second (or just not the 1st second) and the time will always be different from the time that the device is showing (computer, smartphone, ...).
But I would like that both times are matching. So I was wondering if it is possible to start the interval when a new minute starts of if there is another way to get a time update.
EDIT: Current code
componentDidMount() {
setInterval(() => {
this.setState({ currentTime: new Date() })
}, 60 * 1000);
}
You can get fairly close, by calculating the number of seconds until the next minute, and performing a timeout on the difference.
(function showTime(){
console.log('update time');
var time = document.getElementById('time');
var now = new Date();
time.innerHTML = `${now.getHours()}:${now.getMinutes()}`;
setTimeout(showTime, (60 - now.getSeconds()) * 1000);
})();
<div id="time"></div>
Use SetTimeout to call a function that repairs any deviation for each iteration and relaunches with a new call to setTimout.
function repairAndRelaunch (cnt) {
// capture current secs
var secs = (new Date()).getSeconds();
// relaunch with corrected seconds - limit iterations for testing
if (5 > cnt++) setTimeout('repairAndRelaunch(' + cnt + ')', (60-secs)*1000);
// log to observe discrepencies
console.log('for cnt = ' + cnt + ', secs = ' + secs);
};
// test control flow
window.onload = function() {repairAndRelaunch(0);};

Javascript setTimeout and frame rate

I seem to be having some unexpected results with a framerate counter in javascript. Up until recently the counter has been fine and I have been running my little js app at 30fps.
It uses setTimeout() (with a time adjustment to counter the system 'falling behind').
window.requestAnimFrame = (function()
{
return function (callback) {
time += FPS;
Heartbeat._eTime = (new Date().getTime() - Heartbeat._start);
var diff = Heartbeat._eTime - time;
Heartbeat._delta = FPS - diff;
Heartbeat._deltaS = Heartbeat._delta / 1000;
window.setTimeout(callback, FPS - diff);
};
})();
Heartbeat is merely an object that contains the frame rate info.
*Here is my problem: *
_MainLoopHandler: function () {
timer = new Date().getTime();
counter = timer;
while (this._messages.length > 0 && (counter - timer) < 5)
{
// process messages from _messages array
}
counter = new Date().getTime();
// THE ABOVE IS HAPPY AT 30 FPS
while ((counter - timer) < 6) {
1 + 1;
}
// THE ABOVE WHILE IS VERY UNHAPPY :(
}
So the above code block is the function that is called from setTimeout every 33.33 milliseconds (30 fps). if I take the bottom while loop out, the FPS counter will sit happily at 30fps. However, if I leave it in, the FPS counter goes crazy. it goes up to the 200FPS 300FPS then suddenly goes -200FPS -10FPS 0.01FPS. Its completely off the wall. The while loop will only run maybe 10 times per "frame".
Note also, the hard-coded values 5 and 6 are simply a check to see if 5 or 6 milliseconds have passed while processing the loops (for load balance).
Is this simply javascript being unable to handle the amount of info or has anyone else had a similar problem.
Thanks!
I don't really know what's going on, but I think you should use local variables to control your time, constantly reassess counter and process 1 message at a time. Also, I don't really understand that last loop (I've also renamed the variables):
_MainLoopHandler: function () {
var start = new Date().getTime();
var current;
do {
if (this._messages.length === 0) break;
// process 1 message
current = new Date().getTime();
} while (current - start < 5);
}
You can also encapsulate the timing concern in an object (not shown) to streamline the code:
_MainLoopHandler: function () {
var timing = new Timing();
do {
if (this._messages.length === 0) break;
// process 1 message
} while (timing.elapsed() < 5);
}

Can any desktop browsers detect when the computer resumes from sleep?

It would be nice if the computer's 'wake up' event was propagated to the browser and available in the JavaScript API. Does anyone know if anything like this is implemented?
I don't know of any direct method to do this, but one way you could get a good idea of when it happens is to set up a setInterval task that runs, say every 2 seconds, and stores the time it last ran. Then check to see if the last time it ran is very much older than 2 seconds.
var lastTime = (new Date()).getTime();
setInterval(function() {
var currentTime = (new Date()).getTime();
if (currentTime > (lastTime + 2000*2)) { // ignore small delays
// Probably just woke up!
}
lastTime = currentTime;
}, 2000);
One of the problems you might encounter with methods above is that alert boxes or other modal type windows will pause JS execution possibly causing a false wake up indication. One way to solve this problem is to use web workers (supported on newer browsers)....
DetectWakeup.js (must be its own file)
var lastTime = (new Date()).getTime();
var checkInterval = 10000;
setInterval(function () {
var currentTime = (new Date()).getTime();
if (currentTime > (lastTime + checkInterval * 2)) { // ignore small delays
postMessage("wakeup");
}
lastTime = currentTime;
}, checkInterval);
then in your application, use it like this:
var myWorker = new Worker("DetectWakeup.js");
myWorker.onmessage = function (ev) {
if (ev && ev.data === 'wakeup') {
// wakeup here
}
}
This is a little outdated, but based on the answer by Andrew Mu I've created a simple JQuery plugin to do that:
https://github.com/paulokopny/jquery.wakeup-plugin
Usage is simple:
$.wakeUp(function(sleep_time) {
alert("I have slept for " + sleep_time/1000 + " seconds")
});
Hope this will help someone in the future.
Apart from very good answers and explanations by others, you can also depend on online, offline events. Keeping aside whether online is really online or not, usually, this event ALSO gets triggered when user's machine is back from sleep apart from having real internet disconnection.
So, the ideal solution would be having timer check combined with the online and offline events.
var lastTime = (new Date()).getTime();
setInterval(function() {
var currentTime = (new Date()).getTime();
if (currentTime > (lastTime + 2000*2)) { // ignore small delays
setTimeout(function() {
//enter code here, it will run after wake up
}, 2000);
}
lastTime = currentTime;
}, 2000);
Another way, using the session time
setInterval(function(){
let last = parseInt(localStorage.getItem('sessionTime'));
let now = (new Date()).getTime();
const diffTime = Math.abs(now - last + 2000 * 2);
if (diffTime > 480000) {
_this.authService.logout(1);
}
}, 3000);

Categories