I would like to stop a timer after I delete the variable containing the function that ran it.
The following works but requires an extra step:
foo = (function() {
function doSomething() {
console.log('I am running ')
timer1 = setTimeout(doSomething, 2000)
}
doSomething()
console.log('timer is #' + (bob))
return {
stopTimer: function() {
clearTimeout(timer1)
return true
}
}
})()
//
// let it run a while..
//
// later, stop it .. this works but is an extra step
foo.stopTimer()
// no more logs .. success
That is, it stops the timer. However the REAL OBJECTIVE is just to do this:
foo = <new code like a new version overwriting the existing one>
-- or less desirably --
foo = null
And have the timer(s) stop. Is this possible and if so how?
It's possible, but only by using tricks, which I'd highly recommend not doing, because they greatly obfuscate the intent of the code.
By putting foo on the global object (or with with - please don't), you can make it a getter/setter, where the setter will, when invoked, call the stopTimer.
let timer1;
function doSomething() {
console.log('I am running ')
timer1 = setTimeout(doSomething, 1000)
}
doSomething();
Object.defineProperty(
window,
'foo',
{
set(newArg) {
clearTimeout(timer1);
// delete this setter
delete window.foo
window.foo = newArg;
},
configurable: true
}
);
button.onclick = () => {
console.log('stopping timer');
foo = null;
console.log('new value of window.foo:', foo);
};
<button id="button">stop</button>
A more sensible approach, if your objective is to not to have to both have a line that calls foo.stopTimer and also have a line that creates a new timer (or something) would be to create a method that both stops the timer and creates the new desired one at once, like
// callback interval
foo.makeNewTimer(() => console.log('new'), 1000);