...

# using setInterval in loops

glz
12-15-2007, 05: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, 05: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, 06: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, 07: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, 07:58 AM
In Javascript, you can pass functions around just like any other variable (they are objects).

function reallyLongName(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 % 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:

}

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.

setInterval(
function () {