I have a situation like this:
class Thing {
constructor() {
this.timer = setInterval(() => console.log('Hi'), 1000);
}
}
let a = new Thing();
// ... various stuff happens which takes less than 1s ...
a = undefined;
The problem is, the a
instance of Thing
continues to trigger the timer closure after a
has been set to undefined
:
Hi
Hi
Hi
Hi
Hi
Now I could have the parent scope call a method to tell the instance to stop the timer, but the parent doesn't actually know a timer is being used - it's an internal implementation detail of Thing
.
How can Thing
know it's been dereferenced so it can clean up and allow itself to be GCed?
CodePudding user response:
You can use a FinalizationRegistry
:
class Thing {
constructor() {
this.timer = setInterval(() => console.log('Hi'), 1000);
}
}
let a = new Thing();
const registry = new FinalizationRegistry(timer => {
clearInterval(timer);
console.log('Cleared');
});
registry.register(a, a.timer);
a = undefined;
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Note that it might take some time before the object is garbage collected. In my tests of the above code, the interval ran about 5-20 times before being eventually cleared.