MutationObserver ialah mekanisme yang berguna untuk melihat perubahan dalam DOM dan bertindak balas terhadapnya.
Antara muka MutationObserver menyediakan keupayaan untuk melihat perubahan yang dibuat pada pokok DOM.
Berikut ialah contoh yang memerhatikan perubahan kelas tema.
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(); }
Walau bagaimanapun, jika anda terlupa untuk memutuskan sambungan, anda mungkin mendedahkan diri anda kepada kebocoran memori bergantung pada apa yang diakses dari dalam fungsi MutationObserver.
Bukankah bagus untuk mempunyai ujian yang boleh mengesahkan bahawa kami memutuskan sambungan pemerhati kami?
Ternyata adalah mungkin untuk mengesahkan bahawa setiap MutationObserver yang memerhati DOM juga terputus sambungan. (Anda mungkin memerlukan lebih daripada satu ujian jika anda perlu menggunakan laluan kod yang berbeza untuk menyediakan MutationObservers)
Ideanya adalah untuk Mengejek MutationObserver global dengan subolok-olok untuk kaedah pemerhatiannya dan putuskan sambungan. Sebelum olok-olok dikembalikan, kami merekodkannya dalam tatasusunan supaya kami boleh mengesahkan semua kejadian pada penghujung ujian dijalankan.
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(); } }); });
Dengan cara ini, kami boleh mengesahkan bahawa setiap MutationObserver, persediaan semasa ujian, juga terputus sambungan pada penghujung ujian.
Stephen Cooper - Pembangun Kanan di AG Grid
Ikuti saya di X @ScooperDev
Atas ialah kandungan terperinci Uji bahawa setiap MutationObserver diputuskan sambungan untuk mengelakkan kebocoran memori. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!