If I use the setInterval function to call an asynchronous JavaScript function each X seconds will the interval wait X seconds after the previous execution is finished or X seconds after the previous execution is called? E.g. if I display a timeline of the calls is it:
0 sec : setInterval(funcX, 10000)
10 sec : funcX - takes 3 seconds to execute
20 sec : funcX
or
0 sec : setInterval(funcX, 10000)
10 sec : funcX - takes 3 seconds to execute
23 sec : funcX
Taken from Mozilla documentation:
Calls a function or executes a code snippet repeatedly, with a fixed
time delay between each call to that function.
Therefore it's every X seconds. But if the function takes longer than X seconds to execute, then the thread will be locked and will execute when it's free.
For more information on JavaScript timings I recommend John Resig's article How JavaScript Timers Work.
If you wish for it to be X seconds after the function has executed, use setTimeout() and call this at the end of your function:
runFunc();
function runFunc(){
//code here....
setTimeout(runFunc, 3000);
}
This will cause infinite recursion, emulating setInterval(), but only starting the X second delay once the current function has finished executing.
If the function actually takes 3 seconds to execute, you have serious problems.
This is not particularly relevant to you because you are using Ajax, and the actual Ajax call should be practically instantaneous.
If you want the Ajax call to complete before the interval continues again, setInterval is undesirable. Use setTimeout instead.
function atTime() {
ajax().done(function () { setTimeout(atTime, 10000); });
}
atTime();
Related
I am making a timer in javascript. But there is one thing I am not getting.
Here's the code...
var time = 0;
var timeInterval;
var testTime;
//Main code which increases the value of variable time by 1 every second until interval is stopped
timeInterval = setInterval(function (){
time++;
testTime = time;
}, 1000);
//Code to stop the interval after 10 seconds.
setTimeOut(function() {
clearInterval(timeInterval);
},10000);
//Expected value -> 10
//I get -> 0
console.log(testTime)
If I am running a function which increases the value of time by 1 10times by setInterval() method... Why the value of time is not updating?
When you call setInterval, you are asking code to run after a certain amount of time. The setInterval function is an example of a function that takes a function as a parameter.
This means that you're declaring a function and asking setInterval to call it at a later time all in one go. None of what is inside the function will be called until the interval happens.
Your console.log is not inside either of the functions you gave to setInterval or setTimeout, so it will run straight away.
The order of execution is:
Your variables are declared
Your call to ask setInterval to run your function periodically
Your call to ask setTimeout to run your function after 10 seconds
Your console.log is made
At this point, the execution on your main thread ends
The function you gave to setInterval is called a bunch of times
The function you gave to setTimeout is called once
If you want to fix your code, you can put the console.log in the setTimeout function to ask it to run at the end of the 10 seconds (putting it inside step 7).
var time = 0;
// Main code which increases the value of variable time by 1 every second until interval is stopped
var timeInterval = setInterval(function (){
time++;
console.log("time during interval: ", time);
}, 1000);
// Code to stop the interval after 10 seconds.
setTimeout(function() {
clearInterval(timeInterval);
console.log("time at end: ", time);
}, 10000);
Depending on your objective, you might rather simplify your code by calling clearInterval inside your interval function (if(time > 10) clearInterval(...)) to reduce the likelihood of a bug.
The second parameter in the setInterval function is for delaying the executing in milliseconds. and as expected 1000 millisecond will trigger the function every second. but here's a strange thing that I don't really understant. In the second interval, I've set the delay parameter to 1 millisecond and put inside the function incremental number and condition to check for every passed 1000 number.. I was expecting it to behave just like the seconds interval timer. but It doesn't quite run as I hoped.
Is there any explanation for that?
// detect seconds in a second interval timer (works as expected)
setInterval(function() {
console.log('passed second from the secondInterval');
}, 1e3);
// detect seconds in a millisecond interval timer (I don't have any explanation for the behavior).
(function() {
var i = 0;
setInterval(function() {
if (i === 0) {
i++;
return;
}
if (i % 1000 === 0) console.log('passed second from the millisecondInterval');
i++;
}, 1);
})();
check out the example in jsfiddle to see what I mean
http://jsfiddle.net/dwh82zos/
This happens. The sentence is not logged every second, or whatever your machine can. You are running out of memory, can't resolve, first time 6 operations per 1ms and second 3 operations per 1ms.
Take a look of this What is minimum millisecond value of setTimeout? it is about setTimeout but it useful.
My fiddle link is as follows:http://jsfiddle.net/FvYyS/2/
The function call is as follows:
load_timer('0', '6', '9', 0, '0', '', '0');
Actually my issue is the fiddle is not working. The expected behaviour of this code is the timer should decrease second by second and ultimately reaches to zero(i.e. for example the timer should start at 00:06:09 and end at 00:00:00). But it's not working here in the fiddle. The code is working properly in my application but don't know why this code is not working in fiddle. Also one more issue I noticed in my application is the timer is lagging sometime behind. Can anyone please help me in this regard? If you need any further information I'll provide you the same. Thanks in advance.
Your code has the following structure :
var counter = delay;
function loop() {
counter--;
displayTime(delay, counter);
if (counter > 0) {
setTimeout( loop, 1000 );
}
}
2 things :
displayTime() execution takes time : for example, if it takes 0.2 seconds to complete, the loop will be executed every 1.2 seconds (instead of every second)
setTimeout( ..., 1000 ) means "Please dear javascript runtime, can you run my code in 1 second ? If you have other stuff to do, it is ok for me to wait more."
You have the guarantee that there will be at least 1 second between the setTimeout call and your loop excution, but the delay can be longer.
If you want to avoid the time drift, check for the real time on each iteration :
var start = Date.now();
function loop() {
var now = Date.now();
var elapsedTime = now - start; //elapsed time in milliseconds
displayTime(delay, elapsedTime);
if (elapsedTime < delay) {
setTimeout(loop, 1000);
}
}
you have not included the jquery library in your fiddle
See UPDATED FIDDLE
There are several problems with your approach:
Since you do the setTimeout after doing some work, the time it takes for your work to be done will delay the next iterations. You could fix this by moving the setTimeout call to be the first executed and then do the work.
Using setTimeout(f, timeout) guarantees that the f function will be executed at least timeout miliseconds after the setTimeout call. So if for example the browser is busy for 1 second when the call to f should be executed, the call to f is delayed by 1 second. Furthermore, the next call to setTimeout is delayed by that second, so everything coming after that will incur your delay.
A better fix would be to use setInterval which is designed with repeating a task every n miliseconds and alleviates the recurrent delay problem.
Finally, the best solution to the problem is to use Date to determine the start of your counter and show the exact time elapsed by substracting the original time from the current time.
Does the Javascript setInterval method wait (at least) the specified interval between two executions of the specific code, or does it wait that interval in between finishing the previous execution and the beginning of the next execution?
(or, when comparing to Java's ScheduledExecutorService methods - is setInterval similar to scheduleAtFixedRate() or rather scheduleWithFixedDelay()?)
If you call setInterval with 1000 milliseconds interval and callback code takes 100 milliseconds to run, next callback will be executed after 900 milliseconds.
If callback takes 1050 milliseconds, the next one will fire up immediately after the first one finishes (with 50 milliseconds delay). This delay will keep accumulating.
So in Java world this is similar to scheduleAtFixedRate(). If you need scheduleWithFixedDelay() behaviour, you must use setTimeout() and reschedule callback each time it finishes:
function callback() {
//long running code
setTimeout(callback, 1000);
}
setTimeout(callback, 1000);
The code above will wait exactly 1000 milliseconds after callback() finished before starting it again, no matter how long it took to run.
This answer includes help from jfriend00's comment below.
Javascript is single threaded and so the same function can not run twice at the same time. However the setInterval delay does not take into account how long it takes to run the function.
For example, say your setInterval function takes 500 milliseconds to run, and your delay is 1000 milliseconds. This would lead to a 500 millisecond delay before the function starts again.
As you can see in this jsFiddle test case, setInterval tries to keep the interval on time regardless of how long the code that runs on the interval takes as long as that code takes less time than the interval is set for. So, if you have an interval set for 5 seconds and the code that runs on each interval takes 200ms, each interval should still be 5 seconds apart (or as close as a single threaded javascript engine can make it to 5 seconds).
If, on the other hand, the code you run on each interval takes long than the interval time itself to execute, because javascript is single threaded, the following interval will not start on time and will be delayed because of the time overrun of the first interval's code.
Both of these cases can be seen in this working test case by adjusting the delay time.
Working test case here: http://jsfiddle.net/jfriend00/kGQsQ/
UPDATE 2:
OK, looks like it runs the first time after a minute. How do I get it to run onload, then every minute after that?
UPDATE 1:
I've tried: var interval = setInterval(get_reported_incidents, 60000); but nothing happens. in get_reported_incidents(); I just have an alert("hello");.
ORIGINAL QUESTION:
I want to run a function every minute:
get_reported_incidents();
But I am not sure which method is best for this task;
settimeout or setinterval
It's totally personal preference. setInterval has some odd edge cases around what happens when the previous interval's code hasn't finished running before the next interval is due to start (not a problem if your interval is every minute; intervals every second, which one sometimes wants, get a bit tricky).
I tend to prefer chained setTimeout calls (where each schedules the next) because they can't run away with you — your code always has to explicitly say "Okay, and call me back again next time." But properly-written code should work with either.
Chained setTimeout calls are also more well-suited to asynchronous operations, like for instance polling something via ajax, because you don't schedule the next timeout until the ajax operation completes. Using setInterval, because the ajax calls are asynchronous, you could end up overlapping them.
Using setinterval would be the more natural choise. If you use setTimeout, you have to start a new timeout from the event handler.
window.setInterval(get_reported_incidents, 60*1000);
setTimeout runs a command once after a period of time. setInterval runs a command every time interval.
So, to run get_reported_incidents every minute use setInterval.
var interval = setInterval(get_reported_incidents, 60000);
setinterval executes a function at a given interval. settimeout executes a function after a specified wait time, and then exits.
If you are attempting to do a cron-like execution every minute, you will want to use setinterval.
Please see http://javascript.about.com/library/blstvsi.htm for a comparison.
use setTimeout recursively. See here for more information on why setInterval is a poor choice.
function timeout (){
get_reported_incidents();
setTimeout(timeout, 1000 * 60);
}
timeout(); // start
Strictly speaking, setInterval() was designed for repeating events and setTimeout() for one-shot events.
However you will tend to find that with setTimeout() time will "creep" gradually. I've not tried this at 1 minute intervals, but with a 1 second timer I found it happened quite a lot. A clock showing the current time (to the nearest millisecond) would show a steady increase in the millisecond value of "now".
See http://jsfiddle.net/alnitak/LJCJU/ and tweak the interval to see what I mean!
So, for greatest accuracy, I do this:
var timerHandler = function() {
var interval = 60000;
// do some stuff
...
var now = new Date();
var delay = interval - (now % interval);
setTimeout(timerHandler, delay);
};
This is ideal if you want the timer events to be started in sync with the clock on your system, rather than at some unspecified time "roughly every minute".
obviously setinterval might be easier to maintain in your case
get_reported_incidents(); //first call
var interval = setInterval(get_reported_incidents, 60000);
vs
var interval;
function timeout (){
get_reported_incidents();
interval=setTimeout(timeout, 60000);
}
timeout();