如何在模块上下文中取消订阅 Svelte 存储?

huangapple go评论77阅读模式
英文:

How do you unsubscribe from a Svelte store in a module context?

问题

I have the following module:

<script lang="ts" context="module">
  import type { Config } from './types'
  import {
    config,
    // ... several more here
  } from './stores'

  let config_value: Config 
  config.subscribe(value => {
    config_value = value
  })
</script>

But, according to the docs:

The app in the previous example works, but there's a subtle bug — the store is subscribed to, but never unsubscribed. If the component was instantiated and destroyed many times, this would result in a memory leak.

However, since this is context="module", when trying to run an onDestroy method, it produces the following error:

Function called outside component initialization

So I have a couple of questions:

  1. Does this apparent memory leak apply to modules, or only to components?
  2. If so, how do I unsubscribe from these stores?
英文:

I have the following module:

&lt;script lang=&quot;ts&quot; context=&quot;module&quot;&gt;
  import type { Config } from &#39;./types&#39;
  import {
    config,
    // ... several more here
  } from &#39;./stores&#39;

  let config_value: Config 
  config.subscribe(value =&gt; {
    config_value = value
  })
&lt;/script&gt;

But, according to the docs:

> The app in the previous example works, but there's a subtle bug — the store is subscribed to, but never unsubscribed. If the component was instantiated and destroyed many times, this would result in a memory leak.

However, since this is context=&quot;module&quot;, when trying to run an onDestroy method, it produces the following error:

> Function called outside component initialization

So I have a couple of questions:

  1. Does this apparent memory leak apply to modules, or only to components?
  2. If so, how do I unsubscribe from these stores?

答案1

得分: 2

> 这个明显的内存泄漏是否适用于模块,还是只适用于组件?

部分适用,应该只加载一个模块实例,因此这应该只添加一个监听器,而不是每个组件一个,如果有很多组件可能会导致问题。由于没有随时间累积,这可能不被视为泄漏。

> 如果是这样,我该如何取消订阅这些存储?

通常情况下,模块不会卸载,即使卸载,也没有可以订阅的事件。您可以计算组件实例的数量,并在创建第一个组件实例时订阅,然后在销毁最后一个组件实例时取消订阅。

真正的问题是,您为什么要这样做?

context=module 不是 经常或根本不应该使用的东西。在您的示例代码中没有任何理由使用它。

英文:

> Does this apparent memory leak apply to modules, or only to components?

Kind of, there should only be one instance of the module loaded, so this should only add one listener, rather than one per component, which could potentially cause issues if there are many. As there is no accumulation over time, this could be considered to be not a leak.

> If so, how do I unsubscribe from these stores?

Modules generally do not unload and even if they do, there isn't any event for it that could be subscribed to. You could count component instances and subscribe when the first is created and unsubscribe when the last is destroyed.

The real question is, why are you doing this in the first place?

context=module is not something one should need to use often if at all. There is nothing in your example code that would justify using it.

huangapple
  • 本文由 发表于 2023年7月18日 06:05:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76708366.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定