views:

1680

answers:

3

I'm writing a JavaSCript class that has a method that recursively calls itself.

Scheduler.prototype.updateTimer = function () {
    document.write( this._currentTime );
    this._currentTime -= 1000;
    // recursively calls itself
    this._updateUITimerHandler = window.setTimeout( arguments.callee , 1000 );
}

Property description:

_currentTime: the currentTime of the timer in miliseconds.
_updateUITimerHandler: stores the reference so can be used later with clearTimeout().

my problem is where I'm using recursion with setTimeout(). I know setTimeout() will accept some string to execute, or a reference to a function. since this function is method of an object, I don't know how to call it from outside. so I used the second format of setTimeout() and passed in a reference to the method itself. but it does not work.

+1  A: 

Well the first thing to say is that if you're calling setTimeout but not changing the interval, you should be using setInterval.

edit (update from comment): you can keep a reference from the closure if used as a class and setInterval/clearInterval don't require re-referencing.

edit2: it's been pointed out that you wrote calle*e* which will work quite correctly and 100% unambiguously.

Out of completeness, this works:

function f() 
{
  alert('foo');
  window.setTimeout(arguments.callee,5000);
}

f();

so I tried out document.write instead of alert and that is what appears to be the problem. doc.write is fraught with problems like this because of opening and closing the DOM for writing, so perhaps what you needed is to change the innerHTML of your target rather than doc.write

annakata
thanks for the advise. Using the setInterval() is a much better choice. although becuase I'm writing this calss as a library, I wouldn't know the name of the Objects beeing instanciated from my class. so I can not call them inside my own class.
farzad
Aren't you confusing callee with caller ?
AnthonyWJones
ha - quite right I am, calle*e* works absolutely fine, will amend
annakata
A: 

You could hold a pointer towards it...

/* ... */
var func = arguments.callee;
this._updateUITimerHandler = window.setTimeout(function() { func(); }, 1000);
/* ... */
Pablo Cabrera
This doesn't solve the need to access the appropriate instance members. Subsequent func() calls will have 'this' pointing at the window object instead of a specific instance of scheduler
AnthonyWJones
+5  A: 

Try this:-

Scheduler.prototype.startTimer = function() {
  var self = this;
  function updateTimer() {
    this._currentTime -= 1000;
    self.hTimer = window.setTimeout(updateTimer, 1000)
    self.tick()
  }
  this.hTimer = window.setTimeout(updateTimer, 1000)
}
Scheduler.prototype.stopTimer = function() {
    if (this.hTimer != null) window.clearTimeout(this.hTimer)
  this.hTimer = null;
}
Scheduler.prototype.tick = function() {
  //Do stuff on timer update
}
AnthonyWJones
awsome answer. thanks.
farzad
+1 -- @farzad: I think this deserves your up-vote as well (not just your "accepted" tick). ;-)
Tomalak