setInterval incrementally faster [duplicate] - javascript

This question already has answers here:
Changing the interval of SetInterval while it's running
(17 answers)
Closed 5 years ago.
Given a setInterval, can its timer keep getting quicker?
Such as that the code to be ran starts at 2 seconds, then 1.9s, 1.8s, 1.7s, etc...? (at this point I'm not worried about reaching zero or negative.)
I currently have:
let speed = 2000;
let timer = setInterval(function() {
display();
faster();
console.log(speed)
}, speed);
function faster() {
speed -= 100;
}
function display(){
// displays another square on canvas
}
I ask if it is possible because the console.log shows that the speed does indeed decrease, but the display function is not being called at faster intervals; it is always being called every 2 seconds. Therefor the speed of the setInterval is not getting faster....

No. The setInterval() rate is fixed at the value of the second argument when the timer is started.
You can use setTimeout() instead, reestablishing the timer upon each invocation of the callback:
var rate = 100;
setTimeout(function callback() {
// do something
setTimeout(callback, rate - 10);
});

Related

setInterval time not precise [duplicate]

This question already has answers here:
How to create an accurate timer in javascript?
(15 answers)
Closed 5 years ago.
I'm developping an ionic app.
I create a counter with setInterval.
let test = new Date().getTime();
setInterval(() => {
console.log(new Date().getTime() - test);
test = new Date().getTime();
}, 1000);
Problem, the console.log give not the answer 1000. It is completely random and sometimes more thant 3000.
Have you an idea why is it so?
There is no way to guarantee the exact time because even the simplest function like this it takes some millisecond to execute the content inside the interval function. setInterval function only guarantee the time interval.

setInterval 'stacking' up [duplicate]

This question already has answers here:
javascript animation queueing when page does not have focus
(3 answers)
Closed 8 years ago.
Using setInterval to run a function which gives a 'flash' effect to a list.
If I keep the page open, but visit another tab / come back in 10 minutes or so, the setInterval feels like its working every 1 seconds as the function is constantly being called.
Feels to me like its stacking up over time, anyway to fix this?
function flashListItems(){
$('.imageview_navigation li').each(function(i) {
$(this).delay((i++) * 100).fadeTo(200, 0.8).fadeTo(200, 1);
});
}
setInterval(function(){
flashListItems();
}, 10000);
fiddle: http://jsfiddle.net/6w6wrsm0/
There's nothing wrong with your code, some web browers slow these types of intervals down to not cause too much usage. So when the webpage is not used, the fastest a interval can go is usually about 1 sec.
There might be a way to fix this, which is mentioned here:
How can I make setInterval also work when a tab is inactive in Chrome?
Just make your animation function tick by real elapsed time.
var div = $('#my-div');
var leftValue = 0;
var interval = (1000/20); //20fps
var before = new Date();
setInterval(function()
{
now = new Date();
var elapsedTime = (now.getTime() - before.getTime());
if(elapsedTime > interval)
{
//Recover the motion lost while inactive.
leftValue += Math.floor(elapsedTime/interval);
}
else
{
leftValue++;
}
div.css("left", leftValue);
before = new Date();
}, interval);

How would I make a stopwatch in Javascript/jQuery? [duplicate]

This question already has answers here:
How to create a stopwatch using JavaScript?
(7 answers)
Closed 8 years ago.
How would I make a stopwatch in Javascript/jQuery?
I have developed a few methods of my own, here is one using while loops. This stopwatch is merely meant to count for a minute.
function myStopwatch() {
var $count = 0;
while($count < 60) {
$count++;
}
$count.delay(1000); //makes $count one second long
}
myStopwatch()
Using setInterval() may be better idea:
var count=0;
var timer = setInterval(function(){
if(count<60) count++;
else clearInterval(timer);
},3000);
Use setInterval...
var count = 0;
doEverySecond(){
// something to do every second...
count++;
if(count > 60) clearInterval(timer);
}
var timer = setInterval(doEverySecond, 1000)
jQuery's .delay() does not halt the execution of javascript like you're trying to do. It only works with asychronous operations that use the jQuery queue system such as animations which means it will do nothing in your current code since you are not using any jQuery queued operations.
In javascript, the way that you "delay" for one second is to use setTimeout() or setInterval() and specify the callback function that you want called at some future time from now.
setTimeout(function() {
// this code here will execute one second later
}, 1000);
// this code here executes immediately, there is no delay
var x = 1;
So, if you want to wait for something for a minute, you would do this:
// execute some code one minute from now
setTimeout(function() {
// this code here will execute one second later
}, 1000*60);

Javascript countdown is going slow?

I'm trying to make a countdown that is counting down in milliseconds; however, the countdown actually takes much longer than 7 seconds. Any idea as to why?
function countDown(time){
var i = 0;
var interval = setInterval(function(){
i++;
if(i > time){
clearInterval(interval);
}else{
//mining
$('#mining_time').text($('#mining_time').text()-1);
}
}, 1);
}
And I can confirm the varible time passed to the function is correctly set to 7000.
For a mostly-accurate countdown, use setTimeout().
setTimeout(fn, 7e3);
If you absolutely must have it as close to 7 seconds as possible, use a tight poll (requestAnimationFrame()) and look at difference between the time of start and current poll.
var startTime = Date.now();
requestAnimationFrame(function me() {
var deltaTime = Date.now() - startTime;
if (deltaTime >= 7e3) {
fn();
} else {
requestAnimationFrame(me);
}
});
Poly-fill as required.
the most precise way to run something after 7 seconds - is to use setTimeout with 7000 ms interval
a. there is no browser that guarantees an interval to run with 1ms resolution. In the best case it would be 7-10ms
b. there is only one thread in js, so the tasks are queued. It means that the next run will be scheduled to only after the current run is finished.
Some useful reading: http://ejohn.org/blog/how-javascript-timers-work/
No browser will take 1 as parameter for setInterval. Off the top of my head the minimum is 4 ms.
For an accurate result, get the current time, add 7000 ms, and poll (using setInterval or setTimeout) until you reach that new time.
A quick Web search returned this article that provides an example.
[Update] the value of 4 ms is mentioned on this MDN page.

Javascript SetInterval timing issue, total time

base ={time:0};
var loop = 0;
setInterval(function(){
if(base.time === 9000){
move();
base.time = 0;
}
base.time ++;
},1);
Shouldn't the move(); function occur every 9s? I timed it and its much less, why is that?
setInterval will not run every millisecond. There is a minimum possible interval that is longer than that.
If you want something to run in nine seconds, you should use setTimeout() for 9 seconds. Plus your code doesn't reset base.time back to zero so it would only match 9000 once anyway.
If you want it to run every 9 seconds, then you can use setInterval(handler, 9000) or you can use setTimeout(handler, 9000) and then set the next setTimeout in your handler function.
This will execute move() every nine seconds:
var intervalTimer = setInterval(function(){
move();
}, 9000);
Here's a useful article on the topic: http://www.adequatelygood.com/2010/2/Minimum-Timer-Intervals-in-JavaScript.
To reset the time back to 9 seconds when a button is clicked use this code:
var intervalTimer;
function startTimer() {
intervalTimer = setInterval(function(){
move();
}, 9000);
}
function handleClick() {
clearInterval(intervalTimer); // stop currently running interval
startTimer();
}
startTimer();
See it in action here: http://jsfiddle.net/jfriend00/sF2by/.
Intervals are easy as pie!
var move = function(){
alert("move!");
};
setInterval(move, 9000);
See it work here on jsFiddle
You can't count on setInterval actually running every 1 ms. If the CPU is used for another process, it might not run for 1 second. Instead, use one of the following:
function move() {
// Do stuff.
}
// The obvious solution.
// Certain browsers (Chrome) may put the script in "inactive" mode which will
// pause setInterval code. This means move will be run too few times, if you
// actually depend on it being called X times for Y time.
setInterval(move, 9000);
// The other solution.
// Get the delta between each loop and run the move loop as necessary.
// WARNING: This is not efficient, and you should only use this if you have a
// good reason to do so.
// EXTRA WARNING: This code is actually retarded in its current form. It's just
// here to show you how you'd do it. Since you didn't post your
// original problem, it's hard to know what you're really after.
var time = +new Date, frequency = 9000;
setInterval(function () {
var dt = new Date - time;
// Check if we've waited long enough.
if (dt >= frequency) {
// If the process hangs for 20 seconds, this value would be 2. Usually,
// it will be 1.
// Also, Chrome will pause interval counters, so if a tab is inactive,
// this count could be really high when the tab gets focus again.
var times = Math.floor(dt / frequency);
console.log('Moving', times, 'time(s)!');
for (var i = 0; i < times; i++) {
move();
}
// Start counting time from the last update.
time += times * frequency;
}
}, 1); // 1 could probably be much higher here. Depends on your use case.
You wrote in a comment that there is a button which resets the time, and that's why you don't want to just setTimeout for the full delay. Here's how to handle that:
var running;
function start() {
clearInterval(running);
running = clearInterval(function () {
move();
}, 9000);
}
Every time start() is called, the time will be reset to 9 seconds from now, and if 9 seconds elapse, move() will be called and another 9-second interval will start. If you don't actually want it to happen repeatedly, just use setTimeout instead.
The key is using clearInterval (or clearTimeout) to cancel your previous 9-second-delay and start a new one. It is harmless to call clearInterval with a junk value.

Categories