Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why won't this Javascript method keep calling itself?

I have a JavaScript object with a privileged method. When this method has completed, I would like it to call itself (after a small timeout) and continue running indefinitely. Unfortunately, the method only runs twice, then it stops without any error (tested in Chrome and IE with the same results).

The code is as follows:

function Test() {
    // ... private variables that testMethod needs to access ...
    this.testMethod = function() {
        alert("Hello, from the method.");
        setTimeout(this.testMethod, 2000);
    };
}

var myTest = new Test();
myTest.testMethod();

I would expect to get the alert every two seconds, but instead it only shows the alert twice, then stops. You can see a live example here. Any idea why this would be happening?

like image 263
Michael Martin-Smucker Avatar asked Jun 09 '11 19:06

Michael Martin-Smucker


2 Answers

Because this outside the function is not the same as this inside the function. Try instead:

function Test() {
    // ... private variables that testMethod needs to access ...
    var me = this;
    this.testMethod = function() {
        alert("Hello, from the method.");
        setTimeout(me.testMethod, 2000);
    };
}
like image 143
benzado Avatar answered Oct 25 '22 19:10

benzado


When you first call it with "myTest.testMethod();" the "this" keyword is bond to your "myTest" object, when the timeout fires the "window" object is bond to "this" keyword and "this.testMethod" is equivalent to "window.testMethod". Try:

function Test() {
    // ... private variables that testMethod needs to access ...
    this.testMethod = function() {
        alert("Hello, from the method.");
        setTimeout((function(self){
            return function(){self.testMethod();};
        })(this), 2000);
    };
}

var myTest = new Test();
myTest.testMethod();

Or:

function Test() {
    // ... private variables that testMethod needs to access ...
    this.testMethod = function() {
        alert("Hello, from the method.");
        var self = this;
        setTimeout(function(){self.testMethod();}, 2000);
    };
}

var myTest = new Test();
myTest.testMethod();
like image 40
Prusse Avatar answered Oct 25 '22 19:10

Prusse