You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SvelteKit为何在SSR时跳过会引发ReferenceError的代码块?

SvelteKit中{#await}块为何能跳过服务端错误代码?

默认情况下SvelteKit会先执行SSR(服务端渲染)再执行CSR(客户端渲染),因此在服务端直接访问window对象时,会触发ReferenceError错误。

代码示例1:直接调用异步函数(服务端报错)

<script lang="ts">
  import { browser } from "$app/environment";

  async function hello_world() {
    console.log(`hello world from: ${browser ? "client" : "server"}`);
    console.log(window.localStorage);
    console.log("after accessing localStorage");
  }

  hello_world();
</script>

<p>Hello World!</p>

执行报错:

ReferenceError: window is not defined

代码示例2:用{#await}块调用异步函数(服务端无报错)

<script lang="ts">
  import { browser } from "$app/environment";

  async function hello_world() {
    console.log(`hello world from: ${browser ? "client" : "server"}`);
    console.log(window.localStorage);
    console.log("after accessing localStorage");
  }
</script>

{#await hello_world()}
  <p>Hello World!</p>
{/await}

客户端输出:

hello world from: client
<Storage object>
after accessing localStorage

服务端输出:

hello world from: server

原因解析

  1. SSR的异步处理逻辑:
    在SSR阶段,SvelteKit会识别{#await}块中的异步函数调用,不会在服务端完整执行整个函数。当函数内部抛出未捕获的Promise拒绝(这里访问window的同步错误会被自动包装成拒绝的Promise),SvelteKit会终止该函数在服务端的执行,不会继续执行后续代码行,也不会抛出错误中断SSR流程。

  2. 错误的隐式捕获:
    异步函数中同步抛出的错误会自动转为Promise的拒绝状态。{#await}块在服务端会处理这个拒绝:它不会让错误冒泡扩散,仅渲染等待状态的内容;等到客户端CSR阶段,函数会重新执行,此时window对象存在,就能正常完成所有代码逻辑。

  3. 直接调用与{#await}的核心差异:
    代码示例1中直接调用hello_world()时,函数在服务端同步执行,访问window的错误是同步抛出且无任何Promise捕获,因此直接触发ReferenceError中断SSR;而示例2中{#await}块会将函数调用包装进Promise处理逻辑,同步错误被转为Promise拒绝后,SvelteKit的SSR渲染器会处理这个拒绝,避免错误扩散。


内容的提问来源于stack exchange,提问作者Tirafesi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 04:17:07