首頁  >  文章  >  web前端  >  測試每個 MutationObserver 是否已斷開連接以避免記憶體洩漏

測試每個 MutationObserver 是否已斷開連接以避免記憶體洩漏

WBOY
WBOY原創
2024-08-22 22:34:02857瀏覽

Test that every MutationObserver is disconnected to avoid memory leaks

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

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn