我有一个名为[symbol] .svelte的苗条组件,我想在其中启动与流服务的连接以接收服务器发送的事件。我尚未找到成功完成此操作的方法。
由于EventSource仅在浏览器中运行,因此我在onMount
函数中对其进行了初始化,如下所示:
<script>
export let quote;
let sse = {};
onMount(async () => {
sse = new EventSource(`https://myurl.com?symbol=${quote.symbol}`);
sse.onmessage = (event) => {
let response = JSON.parse(event.data);
if(!response.length) return;
quote = response[0];
}
});
onDestroy(() => {
if(sse.readyState && sse.readyState === 1) {
sse.close();
}
})
</script>
<div>{quote.symbol}</div>
除非我导航到使用相同组件的另一条路线,否则此方法工作正常-因为该组件不会卸载和重新安装,onMount()
不会触发,因此不会实例化新的SSE请求。我不知道有什么方法可以轻松地强制重新安装组件,这将是最简单的(相关的github问题在这里)
另一种尝试是使用反应式语句,如下所示:
<script>
export let quote;
let sse = {};
$: {
if(process.browser === true) { //again, this stuff won't run on the server
if(sse.readyState && sse.readyState === 1) {
sse.close();
}
sse = new EventSource(`https://myurl.com?symbol=${quote.symbol}`);
}
}
sse.onmessage = (event) => {
let response = JSON.parse(event.data);
quote = response[0];
console.log(quote);
}
</script>
<div>{quote.symbol}</div>
更改路线时,quote变量也会更改,从而触发反应式语句终止现有的SSE并实例化一个新的SSE。除了onmessage处理程序不会触发之外,可能是因为onmessage处理程序在创建eventsource对象之前已附加。
最后要做的是尝试在反应式语句中使用onmessage处理程序,如下所示:
<script>
export let quote;
let sse = {};
$: {
if(process.browser === true) { //again, this stuff won't run on the server
if(sse.readyState && sse.readyState === 1) {
sse.close();
}
sse = new EventSource(`https://myurl.com?symbol=${quote.symbol}`);
sse.onmessage = (event) => {
let response = JSON.parse(event.data);
quote = response[0];
console.log(quote);
}
}
}
</script>
<div>{quote.symbol}</div>
这里的问题是,由于quote
被重新分配为onmessage
处理程序的产品,因此反应式语句会不断循环触发。
在这一点上我很茫然,任何输入将不胜感激!
听起来好像您想使用{#key ...}
,这会导致其值更改时其内容被拆除并重新创建,包括以下组件:
{#key quote}
<!-- destroyed and recreated whenever `quote` changes -->
<Quote {quote}/>
{/key}
此处的文档:https : //svelte.dev/docs#key
顺便说一句,onDestroy
如果仅用于清理发生在onMount
以下内容中的工作,则不需要使用:
onMount(() => {
const sse = new EventSource(`https://myurl.com?symbol=${quote.symbol}`);
sse.onmessage = (event) => {
let response = JSON.parse(event.data);
if(!response.length) return;
quote = response[0];
}
};
return () => {
if(sse.readyState === 1) {
sse.close();
}
});
});
这样做会更好,因为您没有顶级sse
变量,并且由于返回的清除功能仅需要在浏览器中使用,因此不需要进行占位符ssr = {}
分配或检查sse.readyState
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句