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

Blazor嵌入Teams应用:JS与JS互操作上下文不共享问题

Blazor Teams应用SDK初始化后仍提示未初始化的解决方案

问题背景

我开发嵌入Microsoft Teams的Blazor应用时,使用Teams JS SDK v2.5.0,通过IJSRuntime从C#调用SDK接口。按要求必须先调用microsoftTeams.app.initialize()完成初始化,才能使用其他SDK功能。

为了在JS互操作可用前和Teams交互,我在页面加载时运行Init.js执行初始化和相关操作。但后续通过Blazor的JS互操作调用SDK时,依然抛出错误:

internalAPIs.ts:28 Uncaught (in promise) Error: The library has not yet been initialized

虽然我保存了初始化的Promise,且开发者工具显示该Promise已处于完成状态,但问题依旧。重复调用初始化能临时解决,但会引发其他未知问题。

相关代码如下:

Init.js

let teamsInitPromise;

teamsInitPromise = microsoftTeams.app.initialize();
teamsInitPromise.then(() => {
    microsoftTeams.app.getContext().then((context) => {
        // do stuff
    });
});

interop.razor

await MicrosoftTeams.InitializeAsync();
var context = await MicrosoftTeams.GetTeamsContextAsync();
culture = context.App.Locale;

interop.js

export function getContextAsync() {
    let scopedPromise = teamsInitPromise; // Promise state "Fulfulled" is shown in developer tools
    return new Promise((resolve, reject) => {
        try {
            microsoftTeams.app.getContext().then((context) => {
                resolve(context);
            });
        } catch (e) {
            reject(e);
        }
    });
}

问题诊断

  1. SDK实例不共享:页面加载时Init.js使用的是全局microsoftTeams实例,但Blazor互操作的interop.js可能因模块加载方式,使用了另一个独立的SDK实例,导致初始化状态无法同步。
  2. 未显式等待初始化完成:即使初始化Promise已完成,互操作函数中没有显式await该Promise就调用SDK API,可能在渲染时序异常时出现状态不一致。

解决方案

1. 全局共享初始化Promise

修改Init.js,将初始化Promise挂载到全局window对象,确保所有JS文件都能访问同一个初始化状态:

// 将初始化Promise挂载到全局,避免作用域隔离问题
window.teamsInitPromise = microsoftTeams.app.initialize();
window.teamsInitPromise.then(() => {
    microsoftTeams.app.getContext().then((context) => {
        // 执行初始化后的操作
    });
});

2. 修改互操作函数,等待初始化完成

更新interop.js,确保调用SDK API前等待全局初始化Promise完成:

export function getContextAsync() {
    // 显式等待初始化完成,即使Promise已完成,await也会直接返回结果
    return window.teamsInitPromise.then(() => {
        return microsoftTeams.app.getContext();
    }).catch(err => {
        throw err;
    });
}

// 添加等待初始化的辅助函数,供Blazor调用
export function waitForTeamsInit() {
    return window.teamsInitPromise;
}

3. 调整Blazor代码,避免重复初始化

移除Blazor中重复调用InitializeAsync的代码,改为等待全局初始化完成后再获取上下文:

// 等待全局的SDK初始化完成
await MicrosoftTeams.WaitForTeamsInitAsync();
// 此时SDK已初始化,可安全调用API
var context = await MicrosoftTeams.GetTeamsContextAsync();
culture = context.App.Locale;

4. 确保SDK只加载一次

检查index.html,确保Teams SDK仅通过<script>标签引入一次,避免重复加载导致多实例:

<script src="https://unpkg.com/@microsoft/teams-js@2.5.0/dist/MicrosoftTeams.min.js"></script>

可选:延迟加载Blazor(确保初始化完成后再渲染)

如果需要严格保证Blazor在SDK初始化完成后再加载,可修改index.html的Blazor加载逻辑:

<script>
window.teamsInitPromise = microsoftTeams.app.initialize();
window.teamsInitPromise.then(() => {
    // 初始化完成后再加载Blazor应用
    import('./_framework/blazor.webassembly.js').catch(err => console.error(err));
});
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 09:15:28