面试题答案
一键面试1. 使用createEffect
清理函数管理内存
createEffect
接受一个函数作为参数,该函数返回一个可选的清理函数。当 createEffect
所依赖的响应式数据发生变化,或者组件卸载时,清理函数会被调用。这一特性可用于取消异步任务,防止内存泄漏。
例如,假设我们有两个API请求,使用 fetch
进行数据获取:
import { createEffect, createSignal } from 'solid-js';
const [data1, setData1] = createSignal(null);
const [data2, setData2] = createSignal(null);
createEffect(() => {
let controller1 = new AbortController();
let controller2 = new AbortController();
fetch('api-url1', { signal: controller1.signal })
.then(response => response.json())
.then(data => setData1(data));
fetch('api-url2', { signal: controller2.signal })
.then(response => response.json())
.then(data => setData2(data));
return () => {
controller1.abort();
controller2.abort();
};
});
在上述代码中,当 createEffect
重新运行(由于依赖的响应式数据变化)或者组件卸载时,清理函数会被调用,从而取消正在进行的API请求,避免内存泄漏。
2. Solid.js响应式系统机制与内存管理
Solid.js 的响应式系统通过跟踪响应式数据的依赖关系来决定何时重新运行 createEffect
。只有当 createEffect
依赖的响应式数据发生变化时,createEffect
才会重新执行。这有助于减少不必要的异步任务触发,从而提升性能和避免内存泄漏。
例如,如果我们有一个依赖于某个信号(signal)的 createEffect
:
const [count, setCount] = createSignal(0);
createEffect(() => {
console.log('Effect running with count:', count());
});
只有当 count
信号的值发生变化时,createEffect
才会重新运行。如果 count
没有变化,就不会触发多余的异步任务,减少了潜在的内存泄漏风险。
3. 可能导致内存泄漏的场景及解决办法
- 场景:在
createEffect
中创建了一个定时器,并且没有在组件卸载或createEffect
重新运行时清理定时器。 - 代码示例:
createEffect(() => {
let id = setInterval(() => {
console.log('Interval running');
}, 1000);
// 这里缺少清理函数
});
- 解决办法:添加清理函数来清除定时器。
createEffect(() => {
let id = setInterval(() => {
console.log('Interval running');
}, 1000);
return () => {
clearInterval(id);
};
});
- 场景:在
createEffect
中订阅了一个事件,但是没有在适当的时候取消订阅。 - 代码示例:
createEffect(() => {
window.addEventListener('resize', () => {
console.log('Window resized');
});
// 缺少取消订阅逻辑
});
- 解决办法:在清理函数中取消事件订阅。
createEffect(() => {
const handleResize = () => {
console.log('Window resized');
};
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
});