...

View Full Version : how can I make it not lag? this while loop..



glz
12-15-2007, 02:53 AM
<html>
<body>
<script type="text/javascript">
var now = new Date().getTime();
var endTime = now + ((1000*60)*2); //2 minutes after now

while (now <= endTime) {
var seconds = (endTime - now)/1000;
//document.write("seconds left: " + seconds);
//document.write("<br>");
now = new Date().getTime();
}
document.write("done");
</script>
</body>
</html>

you can run the above code with the write statements commented, or with them uncommented and it will still lag

is it impossible to run a while loop until a certain time has elasped without lag?
yes i'm aware of setinterval and setimout, but these are different things, the above code should still be possible as it is not an infinite loop

How can I fix it?

Trinithis
12-15-2007, 03:04 AM
TimeoutChainer.js
http://trinithis.awardspace.com/TimeoutChainer/TimeoutChainer.js

Test.html


<html>
<body>
<script type="text/javascript" src="TimeoutChainer.js"></script>
<script type="text/javascript">

var now = new Date().getTime();
var endTime = now + ((1000*30)); // 0.5 minutes after now

new TimeoutChainer({
callback: function(tc) {
if(now >= endTime)
tc.clear();
var seconds = (endTime - now) / 1000;
document.body.appendChild(document.createTextNode("seconds left: " + seconds));
document.body.appendChild(document.createElement("br"));
now = new Date().getTime();
},
numTimes: Number.POSITIVE_INFINITY,
args: [TimeoutChainer.SELF]
});

document.body.appendChild(document.createTextNode("done"));
</script>
</body>
</html>

glz
12-15-2007, 04:15 AM
Thanks for the reply, I"m studying this new code/script.. but your code has some initial problems though...

Here is the output I get:

done seconds left: 30
seconds left: 29.89
seconds left: 29.78
seconds left: 29.76
seconds left: 29.75
seconds left: 29.75
seconds left: 29.73
seconds left: 29.72
seconds left: 29.71
seconds left: 29.69
seconds left: 29.67
seconds left: 29.63
//keep counting down, shortened actual output to save space
seconds left: 0.067
seconds left: 0.047
seconds left: 0.037
seconds left: 0.007
seconds left: -0.003


The point of confusion is, why does it echo "done" before the loop commences, its supposed to echo it after the loop is done not before. And why does it have -seconds left at the end? This is also not a good sign, and not the output I wanted.

Trinithis
12-15-2007, 05:42 AM
Well, to be honest, I completely forgot about setInterval despite you mentioning it. That would do a similar job. For good measure, I'll also show one using setTimeout, which is basically what TimeoutChainer does behind the scenes with a few features to spiff it up.

As for the while-loop stalling the computer, it's probably due to the fact that JS is a single threaded language. Also, I would suspect any browser could not handle so much processing. To the browser, it creates the effects of stalling that infinite loops do. As mentioned, since JS is single threaded, any code following the loop will not be executed. Basically, your only viable solution is to use the timeouts.

Here's a revised TimeoutChainer version, an setInterval version, and a setTimeout version of the code.



new TimeoutChainer({
callback: function(tc) {
if(now >= endTime) {
tc.clear();
document.body.appendChild(document.createTextNode("done"));
return;
}
var seconds = (endTime - now) / 1000;
document.body.appendChild(document.createTextNode("seconds left: " + seconds));
document.body.appendChild(document.createElement("br"));
now = new Date().getTime();
},
numTimes: Number.POSITIVE_INFINITY,
args: [TimeoutChainer.SELF]
});




(function() {
if(now >= endTime) {
document.body.appendChild(document.createTextNode("done"));
clearInterval(arguments.callee.interval);
return;
}
var seconds = (endTime - now) / 1000;
document.body.appendChild(document.createTextNode("seconds left: " + seconds));
document.body.appendChild(document.createElement("br"));
now = new Date().getTime();
if(!arguments.callee.interval)
arguments.callee.interval = setInterval(arguments.callee, 0);
})();




(function() {
if(now >= endTime) {
document.body.appendChild(document.createTextNode("done"));
return;
}
var seconds = (endTime - now) / 1000;
document.body.appendChild(document.createTextNode("seconds left: " + seconds));
document.body.appendChild(document.createElement("br"));
now = new Date().getTime();
setTimeout(arguments.callee, 0);
})();

glz
12-15-2007, 07:27 AM
if(!arguments.callee.interval) {
arguments.callee.interval = setInterval(arguments.callee, 0);
}


In your 2nd example where you exemplify the setInterval() method, I dont see any proof within the code that it will loop, except that above line of code. Could you explain how it works in making it loop, what callee is, and that syntax?? I looked the function up on msdn and could not find any further explanation of this syntax. So please explain or point me in the right direction.

Thank you.

P.S. I did in fact run the code, and yes it does loop, how it does it though is what I want to know.

Trinithis
12-15-2007, 08:13 AM
arguments.callee is a reference to the function itself.

So . . .


function abc() {
alert(abc.toString());
alert(arguments.callee.toString());
}

abc();


------------------------------

Functions are objects. In Javascript, you can add properties to objects at runtime.


if(!arguments.callee.interval)
arguments.callee.interval = setInterval(arguments.callee, 1);
Does the running function have a property called interval? If it doesn't, then set-up an interval. setInterval wants a function reference and an interval time. So we send it a reference to the current function via arguments.callee. Because the function has no name, this is the only way to do it.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum