2017-03-03 102 views
2

我有2個APP_INITIALIZER提供程序...第一個提供HTTP請求以獲取環境信息。Angular 2 APP_INITIALIZER執行順序/異步問題

第二個使用環境信息來授權用戶針對OIDC授權服務器端點(從環境調用獲得)。

看起來,儘管使環境服務成爲授權服務的依賴關係,但在環境調用完成之前調用授權服務的APP_INITIALIZER工廠函數。

{ provide: APP_INITIALIZER, multi: true, useFactory: EnvironmentFactory, deps: [] } 
{ provide: APP_INITIALIZER, multi: true, useFactory: AuthorizationFactory, deps: [EnvironmentProvider] } 

提供給APP_INITIALIZER這兩家工廠都簽名:

Factory() { return() => Promise; } 

結果是授權的呼叫提交給undefined,而不是一個正確的URL。

我想過結合工廠 - 但他們在兩個不同的模塊,所以感覺凌亂。引導讚賞!

+0

請提供更多代碼。我猜'AuthorizationFactory'沒有辦法知道'EnvironmentFactory'何時收到響應。 –

+2

我不確定我還能提供什麼。我明白,AuthorizationFactory不知道EnvironmentFactory promise何時解決,我想這基本上是問題的精神。 如何讓一個APP_INITIALIZER等待另一個APP_INITIALIZER來解析。如果可能的話,我寧願不要有一個既能在內部也能做到的工廠。 EnvironmentAndAuthorizationFactory() –

回答

0

我最終將解決的EnvironmentProvider注入到AuthorizationFactory中。

我向EnvironmentProvider添加了一個observable,它隨時發出Authority值的變化。

{ provide: APP_INITIALIZER, multi: true, 
    useFactory: EnvironmentFactory, deps: [EnvironmentProvider] } 

{ provide: APP_INITIALIZER, multi: true, useFactory: AuthorizationFactory, 
    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的訂閱時發出(例如,如果Authority在AuthorizationFactory訂閱之前已解析)。

任何人遇到這個奇怪的原因,爲什麼我不使用toPromise()...我認爲有一些問題(我已提交這裏審查)。 https://github.com/Reactive-Extensions/RxJS/issues/1429

+0

我想你應該返回一個函數,它直接返回一個promise,而不是promise。感謝您的想法! – alexseik