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;

问题是,Thinga实例在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次才最终被清除。