为什么在刺激控制器中断开连接
本文最初发表于 Rails Designer
Stimulus 中的断开生命周期方法是三种生命周期方法之一。另外两种是 **initialize** 和 **connect**。当控制器从 DOM 中移除时,会调用断开连接。为此,Stimulus 使用突变观察器来跟踪 DOM 元素。
在断开连接方法中,您可以执行 **拆卸**、清理等操作。执行此操作的原因取决于您的代码,但范围包括防止内存泄漏、维护浏览器性能和防止意外副作用。
让我们看一些例子:
export default class extends Controller {
connect() {
this.interval = setInterval(() => {
console.log("Run, Forrest, run!");
}, 1000);
}
}如果不清除间隔,它将继续在后台运行,从而导致内存泄漏。
export default class extends Controller {
disconnect() {
clearInterval(this.interval);
}
}或者如果你使用第三方库,如CodeMirror:
import { EditorView } from "@codemirror/view"
export default class extends Controller {
connect() {
this.editor = new EditorView();
}
}清理很简单:
import { EditorView } from "@codemirror/view"
export default class extends Controller {
disconnect() {
this.editor?.destroy();
}
}如果没有它,任何新的“this.editor”实例都会保持其自己的状态,并且编辑器的 DOM 元素可能会保留在内存中。
让我们再看一个可能会破坏你的浏览器的漏洞。💥
export default class extends Controller {
connect() {
navigator.mediaDevices.getUserMedia({ video: true })
.then(stream => {
this.videoStream = stream;
this.element.srcObject = stream;
});
}
}如果不停止视频流,它们将继续在后台运行。然后,在运行多个实例时,这将导致高 CPU 使用率,并可能由于资源不足而导致浏览器崩溃。😬
我们来添加一个断开连接,可以吗?
export default class extends Controller {
disconnect() {
this.videoStream.getTracks().forEach(track => track.stop());
}
}