By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,289 Members | 1,283 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,289 IT Pros & Developers. It's quick & easy.

setTimeout question

P: n/a
Can I have two setTimeouts running at the same time - with two
different intervals?

I want to start one timer and, before it times out, start another one

I've tried this and they seems to interfer with one another.
Apr 3 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Martin said the following on 4/3/2007 5:27 PM:
Can I have two setTimeouts running at the same time - with two
different intervals?
Yes. They don't even know about each other.
I want to start one timer and, before it times out, start another one
Trivial.
I've tried this and they seems to interfer with one another.
How so? Test page that shows them interfering?

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/index.html
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Apr 3 '07 #2

P: n/a
On Tue, 03 Apr 2007 17:45:22 -0400, Randy Webb
<Hi************@aol.comwrote:
>Martin said the following on 4/3/2007 5:27 PM:
>Can I have two setTimeouts running at the same time - with two
different intervals?

Yes. They don't even know about each other.
>I want to start one timer and, before it times out, start another one

Trivial.
>I've tried this and they seems to interfer with one another.

How so? Test page that shows them interfering?
I can't make a test page available to you but here's the code I'm
working with:

This is part of a page in which I'm using an httpRequest to display
some frequently changing information in a table. It's making the
request every 400 ms with the GetScanInfo function. When the data is
received and displayed, the background color of the row is set to
yellow. The ResetColor function is then called with a 700 ms delay to
change the color back to white. It is this ResetColor function that is
not executing.

Do you see anything wrong?

Thanks.


var http = getHTTPObject();
var TheRow;
function handleHttpResponse() {
var Msgs;
if (http.readyState == 4) {
if (http.status == 200) {
Msgs = http.responseText.split("|");
var gSP = parseInt(Msgs[1]);
TheRow = document.getElementById('TableX').rows[gSP];
if (TheRow.cells[5].innerHTML != Msgs[6]) {
TheRow.cells[1].innerHTML = Msgs[2];
TheRow.cells[2].innerHTML = Msgs[3];
TheRow.cells[3].innerHTML = Msgs[4];
TheRow.cells[4].innerHTML = Msgs[5];
TheRow.cells[5].innerHTML = Msgs[6];
TheRow.cells[1].title = 'Time Of Scan: ' + Msgs[6];
TheRow.style.backgroundColor = 'yellow';
window.setTimeout("ResetColor(gSP)",700);
}
NextSP = gSP + 1;
if (NextSP 12) {NextSP = 1};
window.setTimeout("GetScanInfo(NextSP)",400);
}
}
}
function ResetColor(XX) {
document.getElementById('TableX').rows[XX].style.backgroundColor =
'white';
}

function GetScanInfo(SP) {
http.open("GET", "ScanInfo.HTM?" + SP, true);
http.onreadystatechange = handleHttpResponse;
http.send(null);
}
Apr 3 '07 #3

P: n/a
"Randy Webb" <Hi************@aol.comwrote in message
news:jf********************@giganews.com...
Martin said the following on 4/3/2007 5:27 PM:
>Can I have two setTimeouts running at the same time - with two
different intervals?

Yes. They don't even know about each other.
>I want to start one timer and, before it times out, start another one

Trivial.
>I've tried this and they seems to interfer with one another.

How so? Test page that shows them interfering?
var timer1 = window.setTimeout('alert("first");', 1000);
var timer2 = window.setTimeout('window.clearTimeout("' + timer1 + '");', 500);

Believe it or not, I put something like this in my page once, forgot that I was fooling
with them, continued on with the page and could not figure out why nothing happened.

No errors, no anything. I started the script in motion... then halted it.

Dumb.

-Lost
Apr 3 '07 #4

P: n/a
-Lost said the following on 4/3/2007 6:56 PM:
"Randy Webb" <Hi************@aol.comwrote in message
news:jf********************@giganews.com...
>Martin said the following on 4/3/2007 5:27 PM:
>>Can I have two setTimeouts running at the same time - with two
different intervals?
Yes. They don't even know about each other.
>>I want to start one timer and, before it times out, start another one
Trivial.
>>I've tried this and they seems to interfer with one another.
How so? Test page that shows them interfering?

var timer1 = window.setTimeout('alert("first");', 1000);
var timer2 = window.setTimeout('window.clearTimeout("' + timer1 + '");', 500);
Ooops.

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/index.html
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Apr 3 '07 #5

P: n/a
On Apr 4, 8:24 am, Martin <martinval...@comcast.netwrote:
On Tue, 03 Apr 2007 17:45:22 -0400, Randy Webb

<HikksNotAtH...@aol.comwrote:
Martin said the following on 4/3/2007 5:27 PM:
Can I have two setTimeouts running at the same time - with two
different intervals?
Yes. They don't even know about each other.
I want to start one timer and, before it times out, start another one
Trivial.
I've tried this and they seems to interfer with one another.
How so? Test page that shows them interfering?

I can't make a test page available to you but here's the code I'm
working with:

This is part of a page in which I'm using an httpRequest to display
some frequently changing information in a table. It's making the
request every 400 ms with the GetScanInfo function. When the data is
received and displayed, the background color of the row is set to
yellow. The ResetColor function is then called with a 700 ms delay to
change the color back to white. It is this ResetColor function that is
not executing.

Do you see anything wrong?
Yes, see below.

Also, it is a convention that variables starting with an upper case
letter indicate constructor functions, other variables should start
with a lower case letter, e.g. TheRow should be theRow.

>
var http = getHTTPObject();
var TheRow;
function handleHttpResponse() {
var Msgs;
if (http.readyState == 4) {
if (http.status == 200) {
Msgs = http.responseText.split("|");
var gSP = parseInt(Msgs[1]);
Here you declare gSP as a local variable within the handleHttpResponse
function.

TheRow = document.getElementById('TableX').rows[gSP];
Instead of passing a number to your ResetColor function, then having
to go through the whole getElementById thing again, store a reference
to the row and pass that (i.e. instead of passing gSP, pass TheRow).

if (TheRow.cells[5].innerHTML != Msgs[6]) {
TheRow.cells[1].innerHTML = Msgs[2];
TheRow.cells[2].innerHTML = Msgs[3];
TheRow.cells[3].innerHTML = Msgs[4];
TheRow.cells[4].innerHTML = Msgs[5];
TheRow.cells[5].innerHTML = Msgs[6];
TheRow.cells[1].title = 'Time Of Scan: ' + Msgs[6];
TheRow.style.backgroundColor = 'yellow';
window.setTimeout("ResetColor(gSP)",700);
There is no need to prefix setTimeout with window, unless you have a
local variable called setTimeout (which would be a bad idea).

setTimeout will run the code passed to it in a global scope. By that
stage, gSP has gone out of scope and will return "undefined". Pass an
anonymous function object with a closure back to gSP (or theRow)
instead:

setTimeout(function(){ResetColor(gSP)}, 700);

}
NextSP = gSP + 1;
if (NextSP 12) {NextSP = 1};
window.setTimeout("GetScanInfo(NextSP)",400);
This call works because you have (inadvertently?) created NextSP as a
global variable.

}
}
}
function ResetColor(XX) {
document.getElementById('TableX').rows[XX].style.backgroundColor =
'white';
Instead of changing the background colour explicitly, consider just
changing the CSS class, then you only need modify a CSS rule if you
want a different colour combination (which is the point of CSS). :-)
--
Rob

Apr 4 '07 #6

P: n/a
On 3 Apr 2007 22:34:29 -0700, "RobG" <rg***@iinet.net.auwrote:
>On Apr 4, 8:24 am, Martin <martinval...@comcast.netwrote:
>On Tue, 03 Apr 2007 17:45:22 -0400, Randy Webb

<HikksNotAtH...@aol.comwrote:
>Martin said the following on 4/3/2007 5:27 PM:
Can I have two setTimeouts running at the same time - with two
different intervals?
>Yes. They don't even know about each other.
>I want to start one timer and, before it times out, start another one
>Trivial.
>I've tried this and they seems to interfer with one another.
>How so? Test page that shows them interfering?

I can't make a test page available to you but here's the code I'm
working with:

This is part of a page in which I'm using an httpRequest to display
some frequently changing information in a table. It's making the
request every 400 ms with the GetScanInfo function. When the data is
received and displayed, the background color of the row is set to
yellow. The ResetColor function is then called with a 700 ms delay to
change the color back to white. It is this ResetColor function that is
not executing.

Do you see anything wrong?

Yes, see below.

Also, it is a convention that variables starting with an upper case
letter indicate constructor functions, other variables should start
with a lower case letter, e.g. TheRow should be theRow.

>>
var http = getHTTPObject();
var TheRow;
function handleHttpResponse() {
var Msgs;
if (http.readyState == 4) {
if (http.status == 200) {
Msgs = http.responseText.split("|");
var gSP = parseInt(Msgs[1]);

Here you declare gSP as a local variable within the handleHttpResponse
function.

> TheRow = document.getElementById('TableX').rows[gSP];

Instead of passing a number to your ResetColor function, then having
to go through the whole getElementById thing again, store a reference
to the row and pass that (i.e. instead of passing gSP, pass TheRow).

> if (TheRow.cells[5].innerHTML != Msgs[6]) {
TheRow.cells[1].innerHTML = Msgs[2];
TheRow.cells[2].innerHTML = Msgs[3];
TheRow.cells[3].innerHTML = Msgs[4];
TheRow.cells[4].innerHTML = Msgs[5];
TheRow.cells[5].innerHTML = Msgs[6];
TheRow.cells[1].title = 'Time Of Scan: ' + Msgs[6];
TheRow.style.backgroundColor = 'yellow';
window.setTimeout("ResetColor(gSP)",700);

There is no need to prefix setTimeout with window, unless you have a
local variable called setTimeout (which would be a bad idea).

setTimeout will run the code passed to it in a global scope. By that
stage, gSP has gone out of scope and will return "undefined". Pass an
anonymous function object with a closure back to gSP (or theRow)
instead:

setTimeout(function(){ResetColor(gSP)}, 700);

> }
NextSP = gSP + 1;
if (NextSP 12) {NextSP = 1};
window.setTimeout("GetScanInfo(NextSP)",400);

This call works because you have (inadvertently?) created NextSP as a
global variable.

> }
}
}
function ResetColor(XX) {
document.getElementById('TableX').rows[XX].style.backgroundColor =
'white';

Instead of changing the background colour explicitly, consider just
changing the CSS class, then you only need modify a CSS rule if you
want a different colour combination (which is the point of CSS). :-)
Thank you, thank you, thank you! I could NOT figure this out! Your
solution worked perfectly.

Now I'd like to understand WHY it works.

After I had posted my original message, I had discovered that the
problem was that the gSP variable was "not defined" when the
ResetColor function was called. I couldn't figure out how that could
be the case and I still don't understand how it can be so.

The gSP variable is created and assigned a value INSIDE the
handleHttpResponse function. It is used INSIDE this function (to
select TheRow) and it is used again after the call to ResetColor where
it's incremented and assigned to NextSP.

While trying to figure this out, I inserted alerts in various places
and showed that the NextSP variable was, in fact, getting incremented
correctly - which meant that gSP still had it's value when it reached
that point in the routine. So, why wouldn't it get passed to
ResetColor?

I have yet to understand this. Could you possibly educate me or point
me to something where this is explained?

Again, thank you for fixing this for me - it's greatly appreciated.
Apr 4 '07 #7

P: n/a
On Apr 5, 12:30 am, Martin <martinval...@comcast.netwrote:
On 3 Apr 2007 22:34:29 -0700, "RobG" <r...@iinet.net.auwrote:
On Apr 4, 8:24 am, Martin <martinval...@comcast.netwrote:
[...]
window.setTimeout("ResetColor(gSP)",700);
There is no need to prefix setTimeout with window, unless you have a
local variable called setTimeout (which would be a bad idea).
setTimeout will run the code passed to it in a global scope. By that
stage, gSP has gone out of scope and will return "undefined". Pass an
anonymous function object with a closure back to gSP (or theRow)
instead:
setTimeout(function(){ResetColor(gSP)}, 700);
[...]
Thank you, thank you, thank you! I could NOT figure this out! Your
solution worked perfectly.

Now I'd like to understand WHY it works.

After I had posted my original message, I had discovered that the
problem was that the gSP variable was "not defined" when the
ResetColor function was called. I couldn't figure out how that could
be the case and I still don't understand how it can be so.

The gSP variable is created and assigned a value INSIDE the
handleHttpResponse function. It is used INSIDE this function (to
select TheRow) and it is used again after the call to ResetColor where
it's incremented and assigned to NextSP.
Precisely.

While trying to figure this out, I inserted alerts in various places
and showed that the NextSP variable was, in fact, getting incremented
correctly - which meant that gSP still had it's value when it reached
that point in the routine. So, why wouldn't it get passed to
ResetColor?
Because you don't call ResetColor at that point, you pass a *string*
to setTimeout, which evaluates the string at some later time as global
code after the handleHttpResponse function has finished. gSP never
had global scope (in accordance with good practice you declared as
local to handleHttpResponse), so setTimeout can't access it even if it
still exists.

I have yet to understand this. Could you possibly educate me or point
me to something where this is explained?
The issue is explained very thoroughly by Richard Cornford here:

<URL: http://www.jibbering.com/faq/faq_notes/closures.html >

where setTimeout is used as an example. I seem to be posting that
reference quite a lot lately. :-)

The reason that the solution works is that it creates an anonymous
function object in the scope of the handleHttpResponse function and
passes that to setTimeout. This anonymous function has a closure back
to the gSP variable, so it can be resolved when setTimeout runs the
code.

The closure causes the variable (and probably the entire activation
object it is a property of) to still exist. Once setTimeout has run,
if gSP was the only reference to that activation object, then it (the
activation object) is made available for garbage collection.

--
Rob

Apr 4 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.