组件销毁时必须手动调用EventSource.close(),否则连接持续存活;React在useEffect清理函数、Vue2在beforeDestroy、Vue3在onBeforeUnmount中显式关闭并置空实例。

组件销毁时必须手动调用 EventSource.close(),否则连接会持续存活、占用带宽和内存——浏览器不会自动清理未关闭的 SSE 实例。
React 中:在 useEffect 清理函数里关闭
React 组件卸载时,EventSource 实例不会自动销毁。需在副作用清理阶段显式关闭:
- 在
useEffect中创建EventSource实例 - 返回的清理函数中调用
eventSource?.close() - 建议加可选链判断,避免调用已销毁实例的方法
示例:
useEffect(() => {const eventSource = new EventSource('/api/notifications');
eventSource.onmessage = (e) => {/* 处理消息 */};
return () => {
eventSource?.close();
};
}, []);
Vue2 中:用 beforeDestroy 钩子
Vue2 的生命周期钩子明确支持资源清理:
立即学习“Java免费学习笔记(深入)”;
- 在
created或mounted中初始化 SSE 连接 - 在
beforeDestroy中调用关闭方法 - 确保
eventSource是组件实例属性(如this.eventSource)
示例:
export default {data() { return { eventSource: null }; },
created() { this.setupSSE(); },
beforeDestroy() { this.closeSSE(); },
methods: {
setupSSE() { this.eventSource = new EventSource('/api/stream'); },
closeSSE() { this.eventSource?.close(); }
}
};
Vue3 / Composition API:配合 onBeforeUnmount
组合式 API 提供了与 Vue2 beforeDestroy 对应的钩子:
- 使用
onBeforeUnmount注册清理逻辑 - 保持
eventSource在闭包或 ref 中可访问 - 关闭前检查
readyState是否为 0(CLOSED)或 2(OPEN),避免重复 close
示例:
import { onBeforeUnmount, ref } from 'vue';const eventSource = ref(null);
onBeforeUnmount(() => {
if (eventSource.value && eventSource.value.readyState !== 0) {
eventSource.value.close();
eventSource.value = null;
}
});
通用要点:避免“假关闭”和状态残留
仅调用 .close() 不够,还需注意以下细节:
- 关闭后将实例置为
null或undefined,防止后续误用 - 若连接曾用于监听多个事件(
addEventListener),关闭前无需手动移除监听器——close()会自动解绑 - 服务端应配合检测连接断开(如监听
req.on('close')),及时终止上游流,避免资源泄漏 - 不要依赖
error事件来触发关闭——那是异常路径;销毁时的关闭是主动、确定性的操作


















