«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Проверьте, что каждый MutationObserver отключен, чтобы избежать утечек памяти.

Проверьте, что каждый MutationObserver отключен, чтобы избежать утечек памяти.

Опубликовано 25 августа 2024 г.
Просматривать:834

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.

Разве не было бы здорово иметь тест, который мог бы подтвердить, что мы отключаем наших наблюдателей?

Автоматическая проверка кода

Оказывается, можно проверить, что каждый MutationObserver, наблюдающий за DOM, также отключен. (Вам может потребоваться более одного теста, если вам придется использовать разные пути кода для настройки MutationObservers)

Идея состоит в том, чтобы имитировать глобальный MutationObserver с помощью подмоков для его методов наблюдения и отключения. Прежде чем макет будет возвращен, мы записываем его в массив, чтобы иметь возможность проверить все экземпляры в конце тестового запуска.

describe('Mutation Observers Disconnected', () => {

    let originalMutationObserver: typeof MutationObserver;

    const allMockedObservers: any = [];
    const mutationObserverMock = jest.fn().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, настроенный во время теста, также отключается в конце теста.


Стивен Купер — старший разработчик в AG Grid
Следуйте за мной на X @ScooperDev

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/scooperdev/test-that-every-mutationobserver-is-disconnected-to-avoid-memory-leaks-2fkp?1 В случае каких-либо нарушений, пожалуйста, свяжитесь с Study_golang@163. .com, чтобы удалить его
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3