简体   繁体   中英

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

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.

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.

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.

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM