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