setTimeout question

Discussion in 'Javascript' started by Martin, Apr 3, 2007.

  1. Martin

    Martin Guest

    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.
    Martin, Apr 3, 2007
    #1
    1. Advertising

  2. Martin

    Martin Guest

    On Tue, 03 Apr 2007 17:45:22 -0400, Randy Webb
    <> wrote:

    >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);
    }
    Martin, Apr 3, 2007
    #2
    1. Advertising

  3. Martin

    -Lost Guest

    "Randy Webb" <> wrote in message
    news:...
    > 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
    -Lost, Apr 3, 2007
    #3
  4. Martin

    RobG Guest

    On Apr 4, 8:24 am, Martin <> wrote:
    > On Tue, 03 Apr 2007 17:45:22 -0400, Randy Webb
    >
    > <> wrote:
    > >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
    RobG, Apr 4, 2007
    #4
  5. Martin

    Martin Guest

    On 3 Apr 2007 22:34:29 -0700, "RobG" <> wrote:

    >On Apr 4, 8:24 am, Martin <> wrote:
    >> On Tue, 03 Apr 2007 17:45:22 -0400, Randy Webb
    >>
    >> <> wrote:
    >> >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.
    Martin, Apr 4, 2007
    #5
  6. Martin

    RobG Guest

    On Apr 5, 12:30 am, Martin <> wrote:
    > On 3 Apr 2007 22:34:29 -0700, "RobG" <> wrote:
    > >On Apr 4, 8:24 am, Martin <> wrote:

    [...]
    > >> 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
    RobG, Apr 5, 2007
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    15
    Views:
    156
    Giggle Girl
    Apr 21, 2006
  2. Ian A. Mason

    JavaScript Semantics Question (setTimeout)

    Ian A. Mason, Jul 28, 2006, in forum: Javascript
    Replies:
    2
    Views:
    79
    Ian A. Mason
    Jul 30, 2006
  3. Replies:
    0
    Views:
    92
  4. Replies:
    15
    Views:
    192
    Richard Cornford
    Feb 18, 2007
  5. Thomas Allen

    SetTimeout question...

    Thomas Allen, Mar 30, 2009, in forum: Javascript
    Replies:
    34
    Views:
    248
    Dr J R Stockton
    Apr 1, 2009
Loading...

Share This Page