setTimeOut and infinite recursion

P

pengypenguin

As we know, Javascript suffers an insufferable lack of a wait() or
sleep() function, and so setTimeOut must step in to take up the slack.
A function can use setTimeOut like sleep() by calling itself after x
seconds. This begs a few questions: Is this design building enormous
calling stacks to nowhere? Will the users machine eventually run out of
memory space to contain this stack? How can this be avoided?

Thanks,

-- Whit Nelson
 
L

Lee

(e-mail address removed) said:
As we know, Javascript suffers an insufferable lack of a wait() or
sleep() function,and so setTimeOut must step in to take up the slack.

There's good reason why event-driven systems should never truly sleep.
A function can use setTimeOut like sleep() by calling itself after x
seconds. This begs a few questions: Is this design building enormous
calling stacks to nowhere? Will the users machine eventually run out of
memory space to contain this stack? How can this be avoided?

Of course not. setTimeout() doesn't add anything to a call stack,
it inserts something into the event schedule and then returns.
The function continues running and ends long before the next
invocation.

By the way, to "beg the question" doesn't mean what you think it means:
http://begthequestion.info/


--
 
R

RobG

drclue wrote:
[...]
There are a limited number of timers , so
if you use them all up , setTimeout() and setInterval() would
return null in lue of timer id's and do nothing.

What is the limit that you have discovered? There's no limit noted in
either Gecko or MSDN documentation. I tested setting concurrent
timeouts[1] in Firefox and IE - Firefox was happy up to 100,000[2] (and
probably beyond, my patience ran out), IE seems to get lost somewhere
between 60,000 and 70,000. You can set a much higher number
consecutively without any problems - both browsers were happy to set
500,000 consecutive timeouts in blocks of 10,000 set concurrently.

Firefox seems to allocate timer numbers sequentially from 1, IE uses
some other scheme that numbers timeouts around 2.7e7. There is a
simple test below - it will consume quite a bit CPU when running. You
can watch the memory use climb as more timers are set, then see it fall
as they are executed.

If you are setting in excess of say 10,000 timers concurrently there is
something seriously wrong with your application architecture (which is
probably true if you are setting more than about 10 concurrently). And
if you are setting more than 500,000 consecutively, you're probably
expecting to set one every few seconds over several weeks in which case
you need to look seriously at memory management (and whether JavaScript
is the right tool for the job).


<script type="text/javascript">

function emptyFn() {};

var lotsTimer, numRuns = 0;

function setLotsOfTimers( limit ){
++numRuns;
setTimers(limit);
lotsTimer = setTimeout('setLotsOfTimers(' + limit + ');',20000);
}

function setTimers( limit ){
msgString = 'Reached limit: ' + limit;
var msgEl = document.getElementById('xx');
while ( limit-- ){
var x = setTimeout('emptyFn();', 100);
if ('number' != typeof x){
msgEl.innerHTML = 'Didn\'t finish.<br>Last setTimeout: '
+ x + '<br>Runs: ' + numRuns;
if (lotsTimer) clearTimeout(lotsTimer);
return;
}
}
msgEl.innerHTML = msgString + '<br>Last setTimeout: '
+ x + '<br>Runs: ' + numRuns;
}
</script>
<form action="">
<input type="text" name="limit" value="10000">
<input type="button" value="Set timers"
onclick="setTimers( this.form.limit.value );">
<input type="button" value="Set lots..."
onclick="setLotsOfTimers(this.form.limit.value);">
<input type="button" value="Cancel lots"
onclick="if (lotsTimer){clearTimeout(lotsTimer);lotsTimer=null;">
</form>
<div id="xx"></div>



1. "Concurrent" meaning all set within a loop so that all of them are
set before the first one runs

2. I think setting 100,000 concurrent timeouts in a javascript
application is absurd, it was done here purely to see if I could find a
limit. I think the practical limit is probably about 1,000 or less.
 
D

Dr John Stockton

JRS: In article <[email protected]>,
dated Sat, 16 Sep 2006 16:45:02 remote, seen in
As we know, Javascript suffers an insufferable lack of a wait() or
sleep() function, and so setTimeOut must step in to take up the slack.

There is no need for wait() or sleep(), as setTimeout does all that is
required.
A function can use setTimeOut like sleep() by calling itself after x
seconds. This begs a few questions: Is this design building enormous
calling stacks to nowhere?

Of course not. Each currently-waiting timer uses resource, that is all.
Will the users machine eventually run out of
memory space to contain this stack?

Therefore, no.
How can this be avoided?

It cannot be achieved in that fashion.
-- Whit Nelson

Defective signature format.
 
D

Dr John Stockton

JRS: In article <[email protected]>,
dated Sun, 17 Sep 2006 18:19:44 remote, seen in
news:comp.lang.javascript said:
Heres a simplified description with some pseudo code.

Basically you for each wait type event
create an object containing all the information to describe the time
period and the desired action in a self contained way.
perhaps like this.


var aMyWait=[]
var oMyWait={start:new Date().valueOf(),wait:700,szEval:"alert('hi')"}

That seems inefficient. A timeout does not need to know when it
started, nor how long it is; it only needs to know how much longer to
wait. Don't repeat work unnecessarily.
Now take that oMyWait object, and stick it in an array

aMyWait[aMyWait.length]=oMyWait

now have a setInterval pumped function iterate
the array checking each oMyWait type object in your aMyWait array

That is inefficient. Maintain the array in timeout order, and then only
the leading elements need be checked. Use insertion sort, since that
only needs a partial scan of the array at each insertion. Typically,
too, a long timeout will be inserted rarely, so the average insertion
scan will be shortish. (There may be even better ways.)
and when the time has elapsed eval the expression and remove the
object from the array.

There will be no need for eval if instead a function name is in the
Object - just call the function. Another object element can be used to
provide a structure of parameters to the function. That may well be
quicker, and should not be significantly slower.

One should only use eval when it is useful to do so.


Rather than using setInterval, ISTM that one should, before starting the
"current" event(s), set a timeout that will run until the next loaded
event (insertion of a short interval during a long one will need to re-
schedule the event that was being waited for).

It's a good idea to read the newsgroup and its FAQ.
 
P

pengypenguin

Did you call my signature defective? I think your FACE is defective.

Sweet burn.

--------- RALPH waldO EM3rRson! +++++++
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top