?
Solved

using the setTimeout function for multiple instances of an object

Posted on 2003-03-22
9
Medium Priority
?
278 Views
Last Modified: 2012-06-27
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>
0
Comment
Question by:ErezTal
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
9 Comments
 
LVL 4

Expert Comment

by:thanassis
ID: 8186243
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
 

Author Comment

by:ErezTal
ID: 8186373
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
 

Author Comment

by:ErezTal
ID: 8186469
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 1

Expert Comment

by:Antithesis
ID: 8187710
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
 
LVL 1

Accepted Solution

by:
Antithesis earned 225 total points
ID: 8187771
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
 

Author Comment

by:ErezTal
ID: 8188205
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
 
LVL 1

Expert Comment

by:Antithesis
ID: 8207037
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
 

Author Comment

by:ErezTal
ID: 8213074
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
 
LVL 1

Expert Comment

by:Antithesis
ID: 8214929
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

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The task A number given should be formatted for easy reading by separating digits into triads. Format must be made inline via JavaScript, i.e., frameworks / functions are not welcome. So let’s take a number like this “12345678.91¿ and format i…
This article discusses how to create an extensible mechanism for linked drop downs.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…
Suggested Courses

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question