Javascript: How to clear a non-global (closured) setTimeout?
Asked Answered
I

3

6

I'm trying to be a good citizen and keep as much out of the global scope as possible. Is there a way to access setTimeout variables that are not in the global scope?

So that, in this example how would someone cancel 'timer'?

myObject.timedAction = (function(){
    var timer;
        return function(){
            // do stuff

            // then wait & repeat       
            timer = setTimeout(myObject.timedAction,1000);
        };
})();

I've tried clearTimeout(myObject.timedAction.timer,1000); (without success), and not sure what else to try.

Indrawn answered 8/5, 2011 at 1:18 Comment(0)
J
4

You can't unless you have a reference to timer, which you don't because you're declaring it as a variable in a scope. You can do something like:

myObject.timedAction = (function(){
    return function(){
        // do stuff

        // then wait & repeat       
        myObject.timedAction.timer = setTimeout(myObject.timedAction,1000);
    };
})();

clearTimeout(myObject.timedAction.timer);

Note that the above code will only ever allow ONE timer. If you need references to more than one timer, it needs to be adjusted.

Jiggle answered 8/5, 2011 at 1:20 Comment(0)
P
3

The whole point is that the inner variables are private, and inaccessible to the outside world. SO you have to change your approach a bit:

myObject.timedAction = (function(){
    var timer;
    var result = function(){
        // do stuff
        // then wait & repeat       
        timer = setTimeout(myObject.timedAction,1000);
    };

    result.cancel = function() {
        clearTimeout(timer);
    };

    return result;
})();

myObject.timedAction();       // start it
myObject.timedAction.cancel() // end it

So now the timer is only ever accessed from inside the closure. And yes, you can add methods to a function, because JS is awesome.

Pea answered 8/5, 2011 at 1:25 Comment(2)
Wow, "method" and "function" in the same sentence.Sosna
@TomalakGeretkai remember a function inherits from Object. So it's just an object.Marasmus
N
1

Put the timer handle in a property in your object:

myObject.timedAction = function(){
  // do stuff
  // then wait & repeat
  this.timer = window.setTimeout(function(){ myObject.timedAction(); },1000);
};

Note that you should wrap the call from the timer in a function, so that it's called as a method of your object instead of as a global function, otherwise you won't be able to access your object using this.

Now you can stop the timer using:

window.clearTimeout(myObject.timer);
Nighttime answered 8/5, 2011 at 1:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.