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

如何在SvelteKit应用中更早触发客户端SDK导入以规避竞态条件

解决方案

问题的核心是hooks.client.ts的初始化时机仍晚于App B发送消息的时间,要彻底规避竞态条件,你可以从更早的页面加载阶段入手,以下是两种可靠方案:


方案1:直接在入口HTML中提前加载SDK

这是最彻底的方式,HTML的<head>脚本会在SvelteKit应用初始化前执行,完全避免消息错过的可能。

  1. 打开src/app.html文件,在<head>标签内添加SDK的CDN脚本(优先使用官方提供的CDN链接,或unpkg/jsdelivr这类公共CDN):
<head>
  <!-- 原有meta、样式等内容 -->
  <script src="https://unpkg.com/@owlbear-rodeo/sdk@latest/dist/obr.min.js"></script>
</head>
  1. 页面加载时会优先初始化SDK的消息监听器,确保不会漏过App B发送的OBR_READY事件。
  2. 后续在SvelteKit代码中(如hooks、组件),直接使用全局的window.OBR对象即可,无需再通过import导入:
// src/hooks.client.ts
import type { ClientInit } from '@sveltejs/kit';

export const init: ClientInit = async () => {
  console.info("Initializing iframe app.")
  window.OBR.onReady(() => console.log("It works."));
};

方案2:提前捕获消息并缓存,等SDK加载后复用

如果需要保留npm包的导入方式,可在页面最早期手动监听message事件,缓存OBR_READY消息,待SDK加载完成后再触发逻辑:

  1. 在src/app.html的<head>中添加内联脚本,提前监听并缓存消息:
<head>
  <!-- 原有内容 -->
  <script>
    // 缓存OBR_READY消息
    let cachedObrReadyMsg = null;
    window.addEventListener('message', (e) => {
      if (e.data?.id === 'OBR_READY') {
        cachedObrReadyMsg = e;
      }
    });

    // 给SDK的onReady打补丁,缓存消息存在时直接触发回调
    window.addEventListener('load', () => {
      if (window.OBR && cachedObrReadyMsg) {
        const originalOnReady = window.OBR.onReady;
        window.OBR.onReady = (callback) => {
          originalOnReady(callback);
          // 若已捕获消息,立即执行回调
          callback();
        };
      }
    });
  </script>
</head>
  1. 之后正常在hooks.client.ts中导入SDK并注册onReady回调即可,即使消息在SDK加载前发送,缓存的消息也会触发回调。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 13:42:46