setInterval and long running functions - javascript

How does setInterval handle callback functions that take longer than the desired interval?
I've read that the callback may receive the number of milliseconds late as its first argument, but I was unable to find why it would be late (jitter, or long running functions).
And the wonderful follow up, does it behave differently for the common browsers?

Let me quote an excellent article about timers by John Resig:
setTimeout(function(){
/* Some long block of code... */
setTimeout(arguments.callee, 10);
}, 10);
setInterval(function(){
/* Some long block of code... */
}, 10);
These two pieces of code may appear to
be functionally equivalent, at first
glance, but they are not. Notably the
setTimeout code will always have at
least a 10ms delay after the previous
callback execution (it may end up
being more, but never less) whereas
the setInterval will attempt to
execute a callback every 10ms
regardless of when the last callback
was executed.
Intervals may execute back-to-back with no delay if they take long enough to execute (longer than the specified delay).

Related

Javascript timers in which order

See the below code
vat t = setTimeout(x, 1000);
vat t1 = setTimeout(y, 1100);
var t2 = setTimoue(z, 4000);
The order of execution is t, t1 and t2. So, t is executed after 1s. Till here is fine. Then is t1 executed after 100ms(1100 - 1000) or is it executed 1100ms after t is executed?
t1 will be executed 100ms after t was executed.
But actually, if the page is busy, setTimeout may be fired later so that it can less or greater than 100ms.
Above is the correct answer, although I would encourage you, going forward, when possible, to go open up the JavaScript console in your browser and figure it out yourself. console.log(Date.now()) in your code and test it. When I first got into coding, I would always turn to pros for simple questions (out of habit), but in my experience, being successful in coding often means knowing HOW to get the answer, as opposed to just knowing WHAT the answer is.
Additionally, I would argue you're much more likely to remember the answer if you identified it yourself instead of someone just telling you.
Good luck!
If you want to control the order of execution I really think you should sequence the timeouts.
var t = setTimeout(x, 1000);
function x(){
setTimeout(y, 100);
}
function y(){
setTimeout(z, 2900);
}
In any case I'm not sure you should be doing any of this in the first place.
If you want to call one function after another just use the .call or .apply.
take a look at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
JavaScript is single-threaded. If some block of code uses execution thread, no other code can be executed. This means your setTimeout() call must wait until main execution finishes.
[from here]setTimeout behaviour with blocking code

Javascript stack and recursive calls

Assume the following method(Just curious, I'm hopefully fail in js)
foo(0);
function foo(i){
if(i<1000){
setTimeout(function(){foo(i+1);}, 1000);
}
alert('I am foo');
}
So if I got it true, it should alerts around 1000 I am foos after 1000 seconds.
So doesn't it bother the browser about keeping the is in a sort of big stack? it should be too much I think or I'm wrong?
Yes, you will alert 1000 "foo" messages with this code.
However, the browser will not get bothered by the amount of i variables. i is a local variable to foo and as a result, it is only kept around as long as foo is executing. Each time the setTimeout callback is finished executing, i and the entire function's footprint is eligible for garbage collection by the browser (which will happen at an opportune time).
The reason for this is that there is no preserved memory call stack here because of the use of setTimeout. setTimeout does not do anything with a returned value from foo and as a result there are no pointers in memory keeping that function nor its variable environment from being collected.
Your call stack will look like this as your code goes through it's loop:
main() [local foo]
main() -> foo [local i = 0]
main()
(empty)
setTimeout()
setTimeout() -> foo [local i = 1]
setTimeout()
(empty)
setTimeout()
setTimeout() -> foo [local i = 2]
setTimeout()
(empty)
over and over until i equals 1000.
It happens this way because setTimeout is a browser api that waits n amount of time and then inserts the callback into the callback queue. The callback will then get picked up by the event loop and executed when the callstack is empty.
So, no, you aren't in any danger of overloading the browser with stacks or vars or whatever you were worried about. Your callstack will remain small because each time foo is executed, it fires off a setTimeout and returns. the i will stay in memory until the setTimeout's callback gets executed, at which point a new i will be created within the scope created by executing foo. That new i will stay in memory until the next setTimeout executes, on and on.
Here's a video that may help explain how this works. http://www.youtube.com/watch?v=8aGhZQkoFbQ
Firstly in javascript there is no "int" you have to say var i. And it gets alone the type for the declaration. If you want get Information about stack. You can use the debug console. And navigate to the call stacks. Its a nice feature you have also a nice overview. I prefer the Chromes Debugger. You can get there with pressing F12
1000 is in a stack is not a really big size for a browser to deal with.
Moreover, there won't be more than 2 is at the same time (maybe even only one), with each function executing every second.
This code won't load 1000 calls to get triggered with an interval of 1 second, this will chain calls, preventing the stack to get bloated.

Do nothing if the same function is already running

I have a javascript function that runs every 3 seconds, is there any way to do nothing if a previous instance of the function is already running?
I assume you are running heavy function with setInterval and want to skip one tick if previous one has not completed.
Then, instead of
function yourfoo() {
// code
}
setInterval(yourfoo, 3000);
do:
function yourfoo() {
// code
setTimeout(yourfoo, 3000);
}
setTimeout(yourfoo, 3000);
This guarantees next call is not scheduled until previous one is completed.
you could define a boolean flag to indicate the running state of the function on a higher scope, and switch it on or off accordingly.
Yes.
This is done by default.
It's called JavaScript is single threaded.
Two functions can't run at the same time.
Your probably using setInterval which will internally buffer function calls until any currently running code is finished.
JavaScript is single threaded, meaning that only one block of JavaScript will get executed at a given time. So even when the timer fires the execution of the code will be queued until the next available moment. Important to know is that if you're using a setInterval only one interval "fire" will get queued and all others will be dropped until there are no more intervals of this type on the queue.
Here's a great explanation of how this works by jQuery's father John Resig: http://ejohn.org/blog/how-javascript-timers-work/
You could rewrite your code to use setTimeout, because that way you're guaranteed that the next executing of the code will only take place after waiting at least the stated number of milliseconds (can be more if execution is blocked). Using setInterval the blocking could result in a back-to-back execution of the code if the code takes a long time to finish.
So, do something like this to prevent the back-to-back execution:
var nrOfMillisecondsToWait = 200;
setTimeout(function() {
.. your code here
}, nrOfMillisecondsToWait);

Where does JQuery call setInterval for .fadeIn and .fadeOut()?

Here is a source viewer for fadeIn() but it does not link out to custom() for some reason.
Also, as a second question, how does one conceptualize all this code...there are so many function calls that I can't even guess as to how much code actually runs when you call .fadeIn() or .fadeOut().
For example:
fadeIn() calls animate() which calls speed() which calls extend()...
As a third question: is this object oriented programming ?
Thanks.
It doesn't use setTimeout(), it uses setInterval(), which is in custom(), which is called at the bottom of the animate() method.
Here's a good tutorial: http://www.schillmania.com/content/projects/javascript-animation-1/
As explained in the tutorial, setTimeout() schedules an event to occur a certain amount of time after the setTimeout() function is called. The problem it's going to take time for the scheduled function to run, and thus the next timeout is going to be scheduled after the first timeout's delay AND the time it took to execute the code.
If you want:
100ms : function x called
200ms : function x called
300ms : function x called
400ms : function x called
and you do:
function x(){
setTimeout( x , 100);
}
setTimeout( x , 100);
What's going to happen is:
100ms : function x called
first calls execution time + 200ms : function x called
second calls execution time + first calls execution time + 300ms : function x called
third calls execution time + second calls execution time + first calls execution time + 400ms : function x called
So you do:
function x(){
}
setInterval( x , 100);
Make no mistake, this object oriented programming. Functional programming is completely different (usually looks very different too, search for python or haskell). I think you meant "imperative programming" (like C), which isn't functional programming but doesn't have objects either.
jQuery also supports inheritance which is similar to JavaScripts native prototypical inheritance.
setInterval is often a bad option to use . This is because once an interval is set up it will attempt to execute it every N milliseconds regardless of how existing threads are going - so if your browser is choking on some heavy problem already then setInterval is going to add to that. You have to think long and hard about using setInterval especially with older, less thread-aware browsers. more information here: https://stackoverflow.com/a/5479821/1238884
setTimeout is often better since you only queue the next timeout when your process is done - something like this is sometimes better:
function foo(params) {
// do stuff here that might block or take time
setTimeout(function() {
foo(params);
}, 1234);
}

What is a JavaScript 'Call' and how does it relate to efficiency?

I'm doing some testing and optimizing on a JavaScript function I made. I notice that the add-on I'm using in Firefox (FireUnit) gives a return of the number of calls done during the profiling time. Is this the number of http calls made by the script?
Also, can you outline/discuss/grade/explain as to how many calls is considered within a good range? Maybe by giving examples or commonly-used JavaScript functions such as drop-down menus, hide/show images, image slideshow functionality, etc...
Does a call represent any measure of 'work' or merely the iterations performed?
In this context, a call is the amount of times a function has been invoked.
function foo() {
};
foo();
foo();
The function foo has been called/ invoked twice in the above example.
There is no answer for "what is a good range of calls". A function like jQuery will most likely be called a large number of times per page, whereas you would expect a function like init() to be called only once.
A better representation of the efficiency of your functions is their execution time; this records the amount of time taken for the function to execute (almost always recorded in milliseconds). Functions with long execution times could be optimized to lower their execution time and improve the efficiency of your program.
To best spend you time, you could combine the two statistics (call count and execution time), and look at optimizing the functions that are called a large number of times, and have longer execution times.
The number of calls means how many times a given function was run or invoked or executed. There is no good range in the number of calls. This number gives you two most important informations:
First, if some function is called only once and some other function is called 100 times then every optimization in the latter is 100 times more important than in the former. It is often a waste of time to optimize a function called only once, but if a function is called a lot of times then it may be important to see if it is not too slow.
The second thing you can see from the number of function calls is that if some function is called hundreds of times when in fact it always has the same result then it might mean that you are calling it inside a loop when calling it once and storing the value in a variable might be sufficient.
For example this would call the expensiveFunction 1000 times:
for (i = 0; i < 1000; i++) {
array[i] = i + expensiveFunction();
}
While this would call it only once:
value = expensiveFunction();
for (i = 0; i < 1000; i++) {
array[i] = i + value;
}
Seeing that some of your functions was called a lot of times might be a hint that you have some code similar to that example. Of course you can't cache the value every time but sometimes you do and knowing the number of function calls can be useful.

Categories

Resources