
MutationObserver 是一種有用的機制,可以監視 DOM 中的變更並對其做出回應。
MutationObserver 介面提供了監視 DOM 樹所做變更的能力。
這是一個監視主題類別變更的範例。
function setUpThemeClassObservers() {
const observer = new MutationObserver(() => {
const themeClass = this.getThemeClass();
this.fireStylesChangedEvent('themeChanged');
});
observer.observe(this.eGridDiv, {
attributes: true,
attributeFilter: ['class'],
});
// we must disconnect otherwise "this" will not be GC'd
// causing a memory leak
return () => observer.disconnect();
}
但是,如果您忘記斷開連接,則可能會導致記憶體洩漏,具體取決於從 MutationObserver 函數中存取的內容。
有一個測試可以驗證我們是否斷開了觀察者的連接不是很好嗎?
事實證明,可以驗證每個正在觀察 DOM 的 MutationObserver 也已斷開連線。 (如果您必須使用不同的程式碼路徑來設定 MutationObservers,您可能需要多個測試)
這個想法是用子模擬來模擬全域 MutationObserver 的觀察和斷開連接方法。在返回模擬之前,我們將其記錄在一個陣列中,以便我們可以在測試運行結束時驗證所有實例。
describe('Mutation Observers Disconnected', () => {
let originalMutationObserver: typeof MutationObserver;
const allMockedObservers: any = [];
const mutationObserverMock = jest.fn<MutationObserver, [MutationCallback]>().mockImplementation(() => {
const mock = {
observe: jest.fn(),
disconnect: jest.fn(),
takeRecords: jest.fn(),
};
allMockedObservers.push(mock);
return mock;
});
beforeEach(() => {
// Ensure we can restore the real MutationObserver after the test
originalMutationObserver = global.MutationObserver;
global.MutationObserver = mutationObserverMock;
});
afterEach(() => {
global.MutationObserver = originalMutationObserver;
});
test('observer always disconnected after destroy', async () => {
const api = createGrid();
// Perform some actions if required to exercise the code paths
api.destroy();
expect(allMockedObservers.length).toBeGreaterThan(0);
for (const mock of allMockedObservers) {
expect(mock.observe).toHaveBeenCalled();
expect(mock.disconnect).toHaveBeenCalled();
}
});
});
透過這種方式,我們可以驗證在測試期間設定的每個 MutationObserver 在測試結束時也已斷開連線。
Stephen Cooper - AG Grid 資深開發人員
在 X @ScooperDev 上關注我
以上是測試每個 MutationObserver 是否已斷開連接以避免記憶體洩漏的詳細內容。更多資訊請關注PHP中文網其他相關文章!