views:

231

answers:

6

I use the below code to write code to query a web method in a specified interval.

now in the this.Poll function I have to do

this.tmo = setTimeout(this.strInstanceName + ".Poll()", this.iInterval);

instead of

this.tmo = setTimeout(this.Poll(), this.iInterval);

because IE looses the this pointer after setTimeout
So I have to pass the class it's instance name:

    var objPoll = new cPoll("objPoll");


How can I get the instance name without passing it as parameter ?
I want to have it outta there !

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Intervall-Test</title>
    <script type="text/javascript" language="javascript">


        function test()
        {
            alert("Test");
            test.tmo = setTimeout(test, 2000);

            test.Clear = function()
            {
                clearTimeout(test.tmo);
            }
        }




        function cPoll(strInstanceName)
        {
            this.strInstanceName = strInstanceName ;
            this.iInterval = 2000;
            this.tmo=null;
            this.cbFunction=null;

            this.Poll = function()
            {
                this.cbFunction();
                this.tmo = setTimeout(this.strInstanceName + ".Poll()", this.iInterval);
            }

            this.Start = function(pCallBackFunction, iIntervalParameter)
            {


                if(this.tmo != null)
                    this.Stop();

                if(iIntervalParameter && iIntervalParameter > 0)
                    this.iInterval=iIntervalParameter;

                this.cbFunction=pCallBackFunction;
                if(this.cbFunction!=null)
                    this.Poll();
                else
                    alert("Invalid or no callback function specified");
            }

            this.Stop = function()
            {
                if(this.tmo != null)
                {
                    clearTimeout(this.tmo);
                    this.tmo=null;
                }
            }
        }


        function CallBackFunction()
        {
            alert("PollCallBack");
        }

        // test();
        // test.Clear();


        var objPoll = new cPoll("objPoll");
    </script>
</head>

<body>
<h1>Test</h1>

<input type="Button" value="Start polling" onclick="objPoll.Start(CallBackFunction,3000);" />
<input type="Button" value="Stop polling" onclick="objPoll.Stop();" />
</body>
</html>
+2  A: 

Loose the parenthesis in this.Poll(). You call this function right away, not after a time interval. If you loose the brackets, it will pass a function, not a result of it, to setInterval and you won't have any issues.

setTimeout(this.Poll, this.Interval);

Otherwise you call the function right away and nothing holds this pointer anymore, and IE just deletes it.

In fixed variant, this.Poll will hold pointer to this and it won't be deleted.

vava
Disaster strikes even without braces. Do you use IE != 8 ?
Quandary
Do that trick with `self` J-P has posted then. If that doesn't work then your object is being GC'd (or haven't been created) before you call `Start`. So, make sure objPoll is there before you call `Start()` and try to loose `var` before `objPoll = new cPoll("objPoll");`
vava
GC is possible, but it is there when I click Start, because Start is called from the instance. If it wouldn't exist, it wouldn't start.
Quandary
A: 
var self = this;
this.tmo = setTimeout(function(){
     self.Poll();
}, this.iInterval);
J-P
self=this=pointer=null --> self = null
Quandary
What do you mean?
J-P
`this = pointerToInstanceInMemory`, therefore, `self = pointerToInstanceInMemory`
J-P
@J-P: I mean creating an alias that points to an object which is null means the alias is also null...
Quandary
`this` *cannot* be `null` in JavaScript. It's impossible.
J-P
Why not ? A pointer can always be null. Obviously it is possible, and at least it definitely is in IE8
Quandary
I don't see how that could be possible. Please let me know what code makes `this === null` ...
J-P
A: 

I provided an answer for a similar question today in which I created a polling class from scratch. You may want to adopt it for yourself. In the sake of not duplicating, here's a link a link to said question:

Poll the Server with Ajax and Dojo *

* Despite the title, my solution offers both "vanilla" and Dojo styles.

Justin Johnson
A: 

You can use this handy little wrapper to execute a function periodically at given interval (1 sec by default):

function tick(func, interval) {
    return (function() {
        if(func())
            setTimeout(arguments.callee, interval || 1000);
    })();
}

The function is repeated until it returns false:

tick(function() {
   if(should stop) return false;
   do stuff
   return true;
});

If the function is a method, make a closure as shown

// inside your object
var me = this;
tick(function() {
   return me.doStuff();
});
stereofrog
A: 

I've asked another question, the answer is here:

http://stackoverflow.com/questions/2462199/javascript-list-global-variables-in-ie/2462341#2462341

Iterating through the global variables and check whether it equals "this".

Quandary
A: 

I just wanted to say, this self trick has saved me a ton of hair pulling... I didn't think to create a reference like this. It means dynamically-created elements with on click events can call the correct instance of my class. TOO GOOD.