...

View Full Version : using setInterval in loops



glz
12-15-2007, 04:08 AM
Hi i'm scratching my head over achieving similar results with setInterval() function, and how I can keep it from looping infinitely.

I want to do something like this:

var i = 0;
var endTime = now + ((1000*60)*2); // 2 minutes after now
while (now <=endTime) {
i = i + 1;
now = new Date().getTime();
}
document.write("total iterations: " + i);

however you can't do this because of lag issues, so i'll settle for using setinterval on its smallest interval of a millisecond, here is my attempt to translate the above to a setinterval solution:

var endTime = now + ((1000*60)*2); // 2 minutes after now
var intervalID = setInterval(loopFunc(endTime),1);
function loopFunc(endTime,intervalID) {
if (new Date().getTime() <= endTime) {
i = i + 1;
} else {
clearInterval(intervalID);
}
}

as you can see I have prolbems figuring out how to stop the interval from continuing to iterate, and passing the interval id, I'm clueless
Also I'm clueless on echoing the total iterations via this method.

Help me out!
Thanks

Trinithis
12-15-2007, 04:57 AM
setInterval(loopFunc(endTime), 1);

loopFunc(endTime) returns the value undefined, not a function. But setInterval() expects a function as an argument.



var i = 0;
var now = new Date().getTime();
var endTime = now + ((1000*10)*1); // 10secs after now

var intervalID = setInterval(function() {
loopFunc(endTime, intervalID);
}, 1);

function loopFunc(endTime, intervalID) {
if (new Date().getTime() <= endTime) {
i = i + 1;
}
else {
clearInterval(intervalID);
document.body.appendChild(document.createTextNode("total iterations: " + i));
}
}



Note: this version of the code is a little vulnerable. It really should use a closure to do the job. If anything, my second post has robust code. In case you were wondering, it uses a closure, but for a different reason. The function that is assigned to f in that code creates a closure. If you don't understand what one is, please ask me. It's an important concept for more advanced Javascript.

Trinithis
12-15-2007, 05:48 AM
Without creating any globals, it might look like . . .



({
count: 0,
callback: function() {
++this.count;
if(new Date().getTime() < this.end)
return;
document.body.appendChild(document.createTextNode("Total iterations: " + this.count));
clearInterval(this.interval);
},
init: function() {
var t = this, f = function() {
t.callback();
};
this.end = new Date().getTime() + 1000 * 60 * 2;
this.interval = setInterval(f, 1);
}
}).init();

glz
12-15-2007, 06:15 AM
var intervalID = setInterval(function() { loopFunc(endTime, intervalID);}, 0);


I don't understand this line of code, what do you say function() etc... can't you just call the function like:

setInterval("loopFunc(endTime,intervalID)",0);

or

setInterval("loopFunc(+ endTime +, + intervalID +)",0);

i've seen this syntax in some online examples/tuts
can you offer explanation on yours, or offer links to documentation where it explains it?
-thank you

Trinithis
12-15-2007, 06:58 AM
In Javascript, you can pass functions around just like any other variable (they are objects).



function reallyLongName(x) {
alert("Number is " + x);
}

var short = reallyLongName;
short(1); // "Number is 1"

function otherFunc(f) {
f(2);
}
otherFunc(reallyLongName); // "Number is 2"
otherFunc(short); // "Number is 2"


Just like otherFunc, setInterval takes a function as its first argument. Internally, it might look like this (vastly simplified) psuedo-code:



setInterval(func, interval) {
if(time &#37; interval == 0)
func();
setInterval(func, interval);
}


Note that when setInterval calls func, it uses a set of parenthesis with nothing in them. This means that the function's arguments (if any) have the value undefined. The question is how to send setInterval a function and have it execute that function with arguments.

Let's say you want to have setInterval alert "hello" every 30 seconds. Well, what if you did the following:



function alertHello() {
alert("hello");
}

setInterval(alertHello, 30000);


It works!

The problem with this is that you can end up littering your code with a bunch of alertXXXX function declarations if you want to have a series of alerts with different texts.

There turns out to be another way to create a function: the function expression.



// function declaration
// function is created at "compile" time
function x() {...}

// function expression
// function is created at "run" time
var x = function() {...};

// the function() {...} part
// is called a function literal. It is also
// called an anonymous function.


Looking at the function expression version of the code, let's understand how it works. The computer creates a variable called x. Then it asks what x is equal to. It looks to the right of the assignment operator and says "Hey, there's a function literal. I need to create a function on the heap." The computer reads the contents of the function and evaluates it and stores the result on the heap. It is put on the heap because functions are instances of the Function class, with is in turn extended from the umbrella Object class. And hopefully you know that objects are created on the heap. Other variables are created on the stack.

In any case, it's in the heap. Meanwhile, x is yelling at the computer "I still don't know what I'm equal to!" Your computer obliges x and sends it a reference to your new function.

So what about the following?



setInterval(
function () {
alert("hello");
}, 30000);


Let's look again at my setInterval psuedo-code. In specific, look at setInterval's func argument. Just like the complaining x, it asks the computer to assign it a value. The computer looks at the arguments and sees a function literal. It turns it into computer code, tosses the resulting function on the heap, and sends a reference to func.

-----------
As a side note, I was mistaken when I sent setInterval a zero for its interval time. Doesn't work properly in IE. Also, sending strings to setTimeout/setInterval is comparatively slow.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum