Angular 11中MSAL拦截器配置工厂内Promise的then回调未触发问题
问题原因与解决方案
根本原因
- Angular 依赖注入的
useFactory默认执行同步逻辑,你在工厂函数内调用的loadConfig().toPromise()属于异步微任务,会等待当前同步代码全部执行完之后才会被调度。工厂函数会直接返回还未填充数据的protectedResourceMap,此时then回调还没有触发。 - 如果
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
相关产品推荐
相关产品推荐

