getStores().page.subscribe() VS page.subscribe() - 有什么区别?
getStores().page.subscribe() VS page.subscribe() - what's the difference?
我一辈子都无法理解什么时候需要使用 getStores
,如果我使用 page.subscribe()
而不是 getStores().page.subscribe()
会怎样?
有人可以举例说明 page.subscribe()
何时出错,以及什么地方出错了吗?
文档说使用 getStores()
是“安全的”——我不知道那是什么意思。
文档 - https://kit.svelte.dev/docs/modules#$app-stores
Rich Harris 回信 - https://github.com/sveltejs/kit/issues/4078#issuecomment-1048912732
When you import page
, you're not actually importing the page store. That would be impossible, because the stores aren't free-floating objects, they're scoped to your app using Svelte context (if they weren't, on the server they would be shared by everyone who makes a request).
Instead, you're importing this:
getStores
uses context to retrieve the actual app-scoped stores:
But you can only call getContext
during a component's initialisation. Most of the time that's fine, because if you do something like this...
<script>
import { page } from '$app/stores';
</script>
<h1>{$page.url.pathname}</h1>
...Svelte is calling page.subscribe
on your behalf (which in turn calls getStores
, which in turn calls getContext
) during init. But if you tried to subscribe later for some contrived reason...
<script>
import { page } from '$app/stores';
let pathname = 'untracked';
function start_subscribing() {
page.subscribe($page => {
pathname = $page.url.pathname;
});
}
</script>
...then you'd be calling getContext
outside component init, which would fail. If you instead use getStores
...
<script>
import { getStores } from '$app/stores';
const { page } = getStores();
let pathname = 'untracked';
function start_subscribing() {
page.subscribe($page => {
pathname = $page.url.pathname;
});
}
</script>
...you can subscribe safely.
我一辈子都无法理解什么时候需要使用 getStores
,如果我使用 page.subscribe()
而不是 getStores().page.subscribe()
会怎样?
有人可以举例说明 page.subscribe()
何时出错,以及什么地方出错了吗?
文档说使用 getStores()
是“安全的”——我不知道那是什么意思。
文档 - https://kit.svelte.dev/docs/modules#$app-stores
Rich Harris 回信 - https://github.com/sveltejs/kit/issues/4078#issuecomment-1048912732
When you import
page
, you're not actually importing the page store. That would be impossible, because the stores aren't free-floating objects, they're scoped to your app using Svelte context (if they weren't, on the server they would be shared by everyone who makes a request).Instead, you're importing this:
getStores
uses context to retrieve the actual app-scoped stores:But you can only call
getContext
during a component's initialisation. Most of the time that's fine, because if you do something like this...<script> import { page } from '$app/stores'; </script> <h1>{$page.url.pathname}</h1>
...Svelte is calling
page.subscribe
on your behalf (which in turn callsgetStores
, which in turn callsgetContext
) during init. But if you tried to subscribe later for some contrived reason...<script> import { page } from '$app/stores'; let pathname = 'untracked'; function start_subscribing() { page.subscribe($page => { pathname = $page.url.pathname; }); } </script>
...then you'd be calling
getContext
outside component init, which would fail. If you instead usegetStores
...<script> import { getStores } from '$app/stores'; const { page } = getStores(); let pathname = 'untracked'; function start_subscribing() { page.subscribe($page => { pathname = $page.url.pathname; }); } </script>
...you can subscribe safely.