AngularJS通过引入$timeout和$interval等包装器服务,提供了一种使用setTimeout和setInternal的便捷方法。我已经使用AngularJS(1.x(很多年了,在我看来,人们只是设置了它并忘记了它类型的功能。但是,忘记清理计时器可能会导致一些严重的负面后果,从静默失败的代码到通过重复请求使 http 请求过载。
我很好奇滥用$timeout和$interval使用而不清理会导致什么类型的严重副作用?
松散的计时器会产生 2 个主要的严重副作用。一个是特定于AngularJS的,另一个是任何类型的应用程序(特别是GC'ed应用程序(中任何"被遗忘"计时器的一般副作用。
内存泄漏
这是所有GC语言中被遗忘的计时器的常见副作用。如果您忘记了一个计时器,并且您认为您破坏了它周围的范围(即未引用对象(,如果它保留在计时器中,它仍然会保留在周围。例如:
const anObject = {
fn: () => {
console.log("I'm alive")
}
};
setInterval(anObject.fn, 1000)
anObject.fn = null;
即使看起来该函数已被删除(我们也无法访问它(,它仍将保留在堆中,因为它仍然在setInterval
内部引用。
$digest
周期过长
AngularJS的计时器具有常规计时器所没有的特殊行为 - 它们调用$digest
循环。通常这是一件好事,否则如果您在计时器内进行更改,您将不会在控制器和模板中看到数据更新"传播"。
然而,$digest
周期是昂贵的,特别是在较大的应用中。因此,拥有一个频繁的计时器,在应该被破坏的时候不会被破坏,导致应用程序处理观察者的频率超过它需要的频率。这会导致角度视图性能缓慢,并使应用程序滞后。