如何简化SvelteKit中EventSource代码,避免手动调用onDestroy?
简化SvelteKit中EventSource的重复代码
最贴合Svelte便捷风格的解决方案有两种,都能帮你省去手动编写onDestroy的重复逻辑:
方法一:自定义Svelte动作(推荐)
Svelte动作(Action)会自动在组件销毁时执行清理逻辑,完美适配这种需要绑定/解绑的场景。
先在$lib/actions.ts中定义动作:
import type { Action } from 'svelte'; export const useEventSource: Action<HTMLElement, { source: EventSource; event: string; callback: (event: MessageEvent) => void; }> = (_, options) => { const { source, event, callback } = options; source.addEventListener(event, callback); return { destroy() { source.removeEventListener(event, callback); } }; };
组件中使用时,只需绑定到任意元素(比如空<div>):
<script> import { useEventSource } from '$lib/actions'; import { customEventSource } from '$lib/events'; const handleMessage = (event: MessageEvent) => { console.log('event:', event); }; </script> <div use:useEventSource={{ source: customEventSource, event: 'message', callback: handleMessage }} />
动作的destroy回调会自动在组件销毁时触发,帮你移除事件监听,无需手动处理销毁逻辑。
方法二:封装工具函数
如果偏好函数式调用,可将订阅和销毁逻辑封装成工具函数:
// $lib/utils/event-source.ts import { onDestroy } from 'svelte'; export function subscribeToEventSource(source: EventSource, event: string, callback: (event: MessageEvent) => void) { source.addEventListener(event, callback); onDestroy(() => source.removeEventListener(event, callback)); }
组件中只需一行代码完成订阅:
<script> import { subscribeToEventSource } from '$lib/utils/event-source'; import { customEventSource } from '$lib/events'; const handleMessage = (event: MessageEvent) => { console.log('event:', event); }; subscribeToEventSource(customEventSource, 'message', handleMessage); </script>
函数内部已封装onDestroy逻辑,组件无需关心销毁细节。
进阶优化:全局EventSource专用封装
若你的customEventSource是全局单例,可进一步封装成更简洁的专用函数:
// $lib/events.ts import { onDestroy } from 'svelte'; export const customEventSource = new EventSource('/your-event-stream'); export function onCustomEvent(event: string, callback: (event: MessageEvent) => void) { customEventSource.addEventListener(event, callback); onDestroy(() => customEventSource.removeEventListener(event, callback)); }
组件中直接调用即可:
<script> import { onCustomEvent } from '$lib/events'; onCustomEvent('message', (event) => { console.log('event:', event); }); </script>
内容的提问来源于stack exchange,提问作者Fred Hors
相关产品推荐
相关产品推荐

