【问题标题】:Angular 2 APP_INITIALIZER Execution order / async issueAngular 2 APP_INITIALIZER 执行顺序/异步问题
【发布时间】:2017-07-26 03:01:34
【问题描述】:

我有 2 个 APP_INITIALIZER 提供程序...第一个发出 HTTP 请求以获取环境信息。

第二个使用环境信息授权用户针对 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。

我曾考虑将工厂合并 - 但它们位于两个不同的模块中,因此感觉很混乱。感谢指导!

【问题讨论】:

  • 请提供更多代码。我猜AuthorizationFactory 无法知道EnvironmentFactory 何时收到回复。
  • 我不确定我还能提供什么。我知道 AuthorizationFactory 不知道 EnvironmentFactory 承诺何时解决,我想这基本上是问题的精神。如何让一个 APP_INITIALIZER 等待另一个解决。如果可能的话,我不希望有一个在内部同时进行的工厂......例如EnvironmentAndAuthorizationFactory()
  • 我最近遇到了同样的问题,我使用自定义 APP_INITIALIZER 解决了它,以确保初始化顺序。我将此自定义代码分解为可重用的库。随时检查、使用并提供一些反馈:npmjs.com/package/ngx-ordered-initializer

标签: angular


【解决方案1】:

我最终将解析后的 EnvironmentProvider 注入到 AuthorizationFactory 中。

我向 EnvironmentProvider 添加了一个 observable,它会在授权值更改时发出。

{ 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 订阅时发出(例如,如果在 AuthorizationFactory 订阅之前解决了授权)。

任何遇到此问题的人都想知道为什么我不使用 toPromise()... 我认为存在一些问题(我已在此处提交审核)。 https://github.com/Reactive-Extensions/RxJS/issues/1429

【讨论】:

猜你喜欢
  • 2018-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-24
  • 2013-03-15
  • 2015-09-28
  • 2017-06-05
  • 1970-01-01
相关资源
最近更新 更多