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中文網其他相關文章!