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>
ErezTalAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
AntithesisConnect With a Mentor Commented:
Here's a solution that I tested, it's harder to call the setTimeout, but it works:
----------
          var o_id = 0;
          var objs = [];
          function findobj(id)  {
               return objs[id];
          }
          function aObj()  {
               this.id = o_id++;
               objs[this.id] = this;
               this.test = function(f_let)  {
                    outputArea.innerHTML += " " +f_let;
                    setTimeout('findobj(' +this.id+ ').test("' +f_let+ '")', 1000);
               }
          }
          a = new aObj();
          a.test('a');
          b = new aObj();
          b.test('b');
----------
0
 
thanassisCommented:
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>
0
 
ErezTalAuthor Commented:
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.
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
ErezTalAuthor Commented:
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.
0
 
AntithesisCommented:
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.
0
 
ErezTalAuthor Commented:
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>
0
 
AntithesisCommented:
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.
0
 
ErezTalAuthor Commented:
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);

0
 
AntithesisCommented:
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.
0
All Courses

From novice to tech pro — start learning today.