SvelteKit中如何从服务器返回Promise供页面异步等待?
在SvelteKit中实现服务器端异步数据加载并显示加载状态的最优方案
你遇到的核心问题是:SvelteKit的+page.server.js中的load函数会自动等待所有返回的Promise完成,所以你返回的activityPromise实际已经被解析为最终数据,页面拿到的是已完成的Promise,自然看不到加载状态。
下面是两种最优实现方式,推荐优先使用SvelteKit原生的defer特性。
方案一:使用SvelteKit的defer特性(推荐)
defer是SvelteKit专门为这类场景设计的API——允许load函数返回未解析的Promise,页面可以先渲染加载状态,后台等待Promise完成后再更新内容。
代码实现:
- 修改
+page.server.js:
import { getActivities } from '$lib/server/utils.js'; import { defer } from '@sveltejs/kit'; export async function load() { // 用defer包装异步函数,load不会等待它完成 return defer({ activities: getActivities() }); }
+page.svelte保持简洁:
<script> export let data; </script> <h1>Activities</h1> {#await data.activities} Loading activities... {:then activities} {#each activities as activity} <h3>{activity.name} {activity.sport_type}</h3> <p>Details: {activity.map.summary_polyline}</p> {/each} {/await}
方案二:创建API路由+客户端Fetch
如果需要将数据暴露给其他客户端(比如第三方应用),或者需要更灵活的请求控制,可以创建一个服务器端API路由,再在页面中通过fetch发起请求。
代码实现:
- 创建API路由
/routes/api/activities/+server.js:
import { getActivities } from '$lib/server/utils.js'; import { json } from '@sveltejs/kit'; export async function GET() { const activities = await getActivities(); return json(activities); }
+page.svelte中发起请求:
<script> async function fetchActivities() { const res = await fetch('/api/activities'); return res.json(); } </script> <h1>Activities</h1> {#await fetchActivities()} Loading activities... {:then activities} {#each activities as activity} <h3>{activity.name} {activity.sport_type}</h3> <p>Details: {activity.map.summary_polyline}</p> {/each} {/await}
内容的提问来源于stack exchange,提问作者lrfalslev
相关产品推荐
相关产品推荐

