我有2个APP_INITIALIZER提供程序……第一个发出HTTP请求来获取环境信息.
第二个使用环境信息来授权用户针对OIDC Authority服务器端点(从环境调用获得).
看起来,尽管使环境服务成为授权服务的依赖,但在环境调用完成之前调用授权服务的APP_INITIALIZER工厂函数.
{ provide: APP_INITIALIZER,multi: true,useFactory: EnvironmentFactory,deps: [] } { provide: APP_INITIALIZER,useFactory: AuthorizationFactory,deps: [EnvironmentProvider] }
提供给APP_INITIALIZER的两个工厂都是签名:
Factory() { return () => Promise; }
结果是授权调用提交到undefined而不是正确的URL.
我想过把工厂结合起来 – 但它们分为两个不同的模块,所以感觉很麻烦.指导赞赏!
解决方法
我最终将已解析的EnvironmentProvider注入AuthorizationFactory.
我向EnvironmentProvider添加了一个observable,它可以随时更改Authority值.
{ provide: APP_INITIALIZER,deps: [EnvironmentProvider] } { provide: APP_INITIALIZER,deps: [AuthorizationProvider,EnvironmentProvider] } export function AuthorizationFactory (auth: AuthorizationProvider,env: EnvironmentService) { return new Promise((resolve,reject) => env.Authority$() // don't emit until authority provider has a value .skipWhile(authority => !authority) // dispatch the auth command to ngrx/store. .do(() => store.dispatch({ type: 'AuthorizeIdentity' })) // switch to observe identity state .switchMap(() => store.select('Identity')) // don't emit until there is an identity (async authorization complete). .skipWhile(identity => !identity) // finish. .take(1) .subscribe(resolve,reject) }); }
我使用ReplaySubject(1)作为env.Authority $()的源代码.这确保了返回的observable总是在AuthorizationFactory订阅时发出(例如,如果在AuthorizationFactory订阅之前解析了Authority).
任何遇到此问题的人都在想我为什么不使用toPromise()……我认为存在一些问题(我已在此处提交审核).
https://github.com/Reactive-Extensions/RxJS/issues/1429