JavaScript class 实例在取消引用时如何清除计时器?
How can a JavaScript class instance clear timers when it is dereferenced?
我遇到这样的情况:
class Thing {
constructor() {
this.timer = setInterval(() => console.log('Hi'), 1000);
}
}
let a = new Thing();
// ... various stuff happens which takes less than 1s ...
a = undefined;
问题是,Thing
的a
实例在a
设置为[=后继续触发定时器关闭 16=]:
Hi
Hi
Hi
Hi
Hi
现在我可以让父作用域调用一个方法来告诉实例停止计时器,但父作用域实际上并不知道正在使用计时器 - 这是 Thing
的内部实现细节。
Thing
如何知道它已被取消引用以便它可以清理并允许自己被 GC 处理?
您可以使用 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次才最终被清除。
我遇到这样的情况:
class Thing {
constructor() {
this.timer = setInterval(() => console.log('Hi'), 1000);
}
}
let a = new Thing();
// ... various stuff happens which takes less than 1s ...
a = undefined;
问题是,Thing
的a
实例在a
设置为[=后继续触发定时器关闭 16=]:
Hi
Hi
Hi
Hi
Hi
现在我可以让父作用域调用一个方法来告诉实例停止计时器,但父作用域实际上并不知道正在使用计时器 - 这是 Thing
的内部实现细节。
Thing
如何知道它已被取消引用以便它可以清理并允许自己被 GC 处理?
您可以使用 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次才最终被清除。