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().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
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3