如何可以一个JavaScript类实例清除定时器时,它被取消引用?



我有一个这样的情况:

class Thing {
constructor() {
this.timer = setInterval(() => console.log('Hi'), 1000);
}
}
let a = new Thing();
// ... various stuff happens which takes less than 1s ...
a = undefined;

问题是,Thinga实例在a被设置为undefined后继续触发定时器关闭:




你好你好你好

现在我可以让父作用域调用一个方法来告诉实例停止计时器,但是父作用域实际上并不知道计时器正在被使用——这是Thing的内部实现细节。

Thing如何知道它已被解引用,以便它可以清理并允许自己被GCed?

您可以使用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;

注意,在对象被垃圾收集之前可能需要一段时间。在我对上述代码的测试中,间隔在最终被清除之前运行了大约5-20次。