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

Angular 11中MSAL拦截器配置工厂内Promise的then回调未触发问题

问题原因与解决方案

根本原因

  1. Angular 依赖注入的 useFactory 默认执行同步逻辑,你在工厂函数内调用的 loadConfig().toPromise() 属于异步微任务,会等待当前同步代码全部执行完之后才会被调度。工厂函数会直接返回还未填充数据的 protectedResourceMap,此时 then 回调还没有触发。
  2. 如果 jsonAppConfigService.loadConfig() 返回的 Observable 没有触发 complete 事件,RxJS 的 toPromise() 会一直处于等待状态,永远不会执行后续的 then 回调,这也是断点无法命中的常见场景。如果请求过程抛出异常进入 catch 分支,也不会触发 then 逻辑。

修复方案

使用 Angular 内置的 APP_INITIALIZER 令牌,在应用启动、MSAL 拦截器配置初始化之前,提前完成配置加载,后续 MSAL 配置工厂就可以直接同步使用已加载完成的配置项。

步骤1:注册APP_INITIALIZER提前加载配置

在 app.module.ts 的 providers 数组中新增如下提供者:

import { APP_INITIALIZER } from '@angular/core';

export function appInitializerFactory(jsonAppConfigService: JsonAppConfigService) {
  // 应用启动前会等待该Promise resolve之后再继续后续初始化流程
  return () => jsonAppConfigService.loadConfig().toPromise();
}

@NgModule({
  // ...其他配置
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: appInitializerFactory,
      deps: [JsonAppConfigService],
      multi: true
    },
    // 原有的MSAL_INTERCEPTOR_CONFIG注册保持不变
    {
      provide: MSAL_INTERCEPTOR_CONFIG,
      deps: [JsonAppConfigService],
      useFactory: MSALInterceptorConfigFactory,
    }
  ]
})

步骤2:改造MSAL配置工厂函数

移除工厂函数内的异步逻辑,直接同步填充资源映射表即可:

export function MSALInterceptorConfigFactory(jsonAppConfigService: JsonAppConfigService): MsalInterceptorConfiguration {
  const protectedResourceMap = new Map<string, Array<string>>();
  const resource = "asdfd";

  // 配置已经在APP_INITIALIZER阶段加载完成,可直接使用
  protectedResourceMap.set('https://graph.microsoft.com/v1.0/me', ['user.read', 'mail.read']);
  protectedResourceMap.set(`${jsonAppConfigService.apiEndPoint}api/method1`, [resource]);
  protectedResourceMap.set(`${jsonAppConfigService.apiEndPoint}api/method2`, [resource]);
  protectedResourceMap.set(`${jsonAppConfigService.apiEndPoint}api/method3`, [resource]);
  protectedResourceMap.set(`${jsonAppConfigService.apiEndPoint}api/method4`, [resource]);
  protectedResourceMap.set(`${jsonAppConfigService.apiEndPoint}api/method5`, [resource]);
  protectedResourceMap.set(`${jsonAppConfigService.apiEndPoint}api/method6`, [resource]);
    
  return {
    interactionType: InteractionType.Redirect,
    protectedResourceMap
  };
}

注意事项

确认 jsonAppConfigService.loadConfig() 返回的 Observable 会正常触发 complete 事件:如果是用 Angular HttpClient 发起的请求默认会在请求结束后自动 complete,如果你是自定义 Observable 需要手动调用 complete() 才能让 toPromise() 正常 resolve。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:06:04