MutationObserver ist ein nützlicher Mechanismus, um auf Änderungen im DOM zu achten und darauf zu reagieren.
Die MutationObserver-Schnittstelle bietet die Möglichkeit, auf Änderungen zu achten, die am DOM-Baum vorgenommen werden.
Hier ist ein Beispiel, das auf einen Themenklassenwechsel achtet.
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(); }
Wenn Sie jedoch vergessen, die Verbindung zu trennen, kann es zu Speicherverlusten kommen, je nachdem, worauf innerhalb der MutationObserver-Funktionen zugegriffen wird.
Wäre es nicht großartig, einen Test zu haben, der bestätigen kann, dass wir unsere Beobachter abkoppeln?
Es stellt sich heraus, dass es möglich ist, zu validieren, dass jeder MutationObserver, der das DOM beobachtet, ebenfalls getrennt ist. (Möglicherweise benötigen Sie mehr als einen Test, wenn Sie unterschiedliche Codepfade ausführen müssen, um die MutationObservers einzurichten)
Die Idee besteht darin, den globalen MutationObserver mit Sub-Mocks für seine Beobachtungs- und Trennmethoden zu verspotten. Bevor der Mock zurückgegeben wird, zeichnen wir ihn in einem Array auf, damit wir am Ende des Testlaufs alle Instanzen validieren können.
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(); } }); });
Auf diese Weise können wir validieren, dass jeder MutationObserver, der während des Tests eingerichtet wurde, am Ende des Tests auch getrennt wird.
Stephen Cooper – Senior Developer bei AG Grid
Folge mir auf X @ScooperDev
Das obige ist der detaillierte Inhalt vonTesten Sie, dass jeder MutationObserver getrennt ist, um Speicherlecks zu vermeiden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!