Link to home
Start Free TrialLog in
Avatar of ErezTal
ErezTal

asked on

using the setTimeout function for multiple instances of an object

i have several instances of an object, and a method that calls itself repeatedly with setTimeout. if just one instance uses it then there is no problem. once a second ones comes it "overrides" the previous one and now the second instance has 2 occurences of the method.

I made the following example to illustrate my problem - instead of seeing on the screen 'a b a b a b' it comes out as 'a b b b b b b'. u can see the "b"'s coming out in pairs.


<HTML>
<script>


function aObj()
{
   this.test=recursiveFunc;

}

function recursiveFunc(letter)
{
   tempObj=this;
   tempLetter=letter

   outputArea.innerHTML+=" "+letter;
   
   setTimeout("tempObj.test(tempLetter)",2000);
}

</script>

<body>
   <div id="outputArea" style='position:absolute;top:100';left:100'></div>
   <script>
      var a=new aObj();
      var b=new aObj();
      a.test("a");
      b.test("b");
   </script>
</body>
</HTML>
Avatar of thanassis
thanassis

try this:

<HTML>
<script>


function aObj()
{
  this.test=recursiveFunc;

}

function recursiveFunc(letter)
{
  tempObj=this;
  tempLetter=letter

  outputArea.innerHTML+=" "+letter;
 
  setTimeout("tempObj.test(tempLetter)",2000);
}

</script>

<body>
  <div id="outputArea" style='position:absolute;top:100';left:100'></div>
  <script>
     var a=new aObj();
     a.test("a b");
  </script>
</body>
</HTML>
Avatar of ErezTal

ASKER

That helps the specific problem but that wasnt my question. the "a b" thing is just an illustration. i have a more complicated object that has several instances that all run at once. each should have his own timing, so putting them all in one function wont help also.
Avatar of ErezTal

ASKER

That helps the specific problem but that wasnt my question. the "a b" thing is just an illustration. i have a more complicated object that has several instances that all run at once. each should have his own timing, so putting them all in one function wont help also.
Put the definitions of the function in the object itself, that way you're creating two different functions, not two functions referencing one.
----------
function aObj()
{
  this.test=function(letter) {
    tempObj=this;
    tempLetter=letter

    outputArea.innerHTML+=" "+letter;
 
    setTimeout("tempObj.test(tempLetter)",2000);
  }
}
----------
But as I look at that code, I can't help but think that tempObj isn't going to be passed correctly...if it works for you let me know.  If it doesn't, I'll make a better solution.
ASKER CERTIFIED SOLUTION
Avatar of Antithesis
Antithesis

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ErezTal

ASKER

This helped me but in fact its not exactly the whole answer.

from your example i took one thing and mine worked -
having the function inside the object constructor doesnt change anything (and shouldnt!?).
The whole problem lied in the setTimeout declaration itself -

if u put

window.setTimeout("tempObj.test('"+letter+"')",2000);

instead of

tempLetter=letter
setTimeout("tempObj.test(tempLetter)",2000);

The real question is what exactly happend here? did something with the pointers in the memory get mixed up along the way?
Antithesis still gets the points but it would be great if someone can explain this.

here is the whole script as it works without the extra complications :)

<script>
function aObj()
{
   this.test=recursiveFunc;
}

function recursiveFunc(letter)
{
   tempObj=this;
   outputArea.innerHTML+=" "+letter;
   window.setTimeout("tempObj.test('"+letter+"')",2000);
}

</script>

<body>
<div id="outputArea" ></div>
<script>
   var a=new aObj();
   var b=new aObj();
   a.test("a");
   b.test("b");
</script>
</body>
The problem is that you're sending a pointer to 'letter'.  JavaScript's scopes aren't defined very well, and it is considered a global variable.  Your code SHOULD produce an error, because the code inside the quotes is eval'd, making it global.  tempObj is a local variable that shouldn't be able to be eval'd.  But since JavaScript doesn't handle scopes very well, it's not a problem.
Avatar of ErezTal

ASKER

Actualy my other post is wrong.

The example I posted gives the a b a b correctly - but from the wrong objects!! If u add an id variable to the object and made the function write the letter write the current object's id you would get only one object all the time but a different letter.

The following good solution is still a bit simpler than antithesis's - the findobj function is not neccesary. This DOES work ok if the function is declared outside of the object declaration.

setTimeout("objs["+this.id"].test('"+f_let+"'),1000);

Yeah, I just realized that.  tempObj becomes a global variable and is over written by the second object.  I usually use a function for that in case I want it to do something more complicated, but the array works fine for your case.

Just remember you should never use temporary variables in eval'd code, that can only lead to problems.