我知道有一些关于此的讨论。例如这里:
https://github.com/sveltejs/kit/discussions/8640
但是,我还是没有完全理解。我有一个
+page.svelte
和相应的 +page.js
文件。在 +page.js
文件中,我获取了一些外部数据。这可能需要一点时间。在这样做的同时,我想让用户至少知道数据已被获取或其他什么。或者甚至渲染不依赖于数据本身的标记。
+page.js
中的代码看起来像这样:
import { fetchAllData } '$lib/utils';
export async function load({ fetch, url }) {
let id = url.searchParams.get('id');
let data = fetchAllData(id, fetch);
return { data };
}
我想知道我是否/如何可以在
+page.svelte
中做这样的事情
<script>
export let data;
</script>
{#await data}
waiting
{:then d}
respo
{/await}
虽然 H.B. 的答案在技术上是正确的,但我认为
+page.js
不是适合您的用例的正确工具。
使用
+page.js
而不是在 onMount
回调中获取的全部目的是避免“加载”问题。
让我解释一下,
+page.js
被执行:
+page.js
(页面A和B都需要是同一个SvelteKit项目内的路由)对于第一种情况,数据加载是在服务器上处理的,在数据加载之前页面甚至不会渲染。因此,用户将不得不等待一段时间,同时盯着空白屏幕。如果这需要很长时间,他们可能会觉得您的网站很慢。
对于第二种情况,数据加载实际上是在页面 A 中处理的,而不是页面 B 中。就像用户单击页面 A 上的链接,但不会导航到页面 B 直到
+page.js
完成执行。因此,如果花费很长时间,用户会停留在页面 A,并且可能会认为他们错过了点击该链接的机会,并且可能会再次点击它。
了解这种行为应该可以帮助您确定
+page.js
是否是解决您问题的正确工具。
我的建议是,
+page.js
,您不必担心加载状态。+page.js
。您应该只使用旧的 onMount(() => fetch(...))
并显示加载指示器以让用户保持耐心。+page.js
专为“正常用例”而设计,无需费力使用该工具,只需选择正确的工具即可。
编辑:在 v2 中,不会自动等待顶级承诺。
data
中的顶级承诺在渲染页面之前会自动等待,您必须将承诺分配给更深层次的属性,例如
return { deferred: { data: fetchAllData(id, fetch) } }
{#await data.deferred.data}
(建议重命名,
data
不是很有描述性,并且页面数据变量也已经被称为data
。)
您几乎已经回答了自己的问题,这是他们官方文档的片段(下面的链接),因此效果非常好。
<script>
let promise = getRandomNumber();
async function getRandomNumber() {
const res = await fetch(`/tutorial/random-number`);
const text = await res.text();
if (res.ok) {
return text;
} else {
throw new Error(text);
}
}
function handleClick() {
promise = getRandomNumber();
}
</script>
<button on:click={handleClick}>
generate random number
</button>
{#await promise}
<p>...waiting</p>
{:then number}
<p>The number is {number}</p>
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
https://svelte.dev/examples/await-blocks
这是一个例子。我基于你的代码:-
https://svelte.dev/repl/e81ca49d739b4f86a2753aed59443467?version=3.59.1