Angular 2 APP_INITIALIZER 执行顺序/异步问题

标签 angular

我有 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。

我考虑过合并工厂 - 但它们位于两个不同的模块中,所以感觉很乱。指导表示赞赏!

最佳答案

我最终将已解析的 EnvironmentProvider 注入(inject)到 AuthorizationFactory 中。

我向 EnvironmentProvider 添加了一个可观察对象,它会在 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$() 的来源。这确保返回的可观察对象始终在 AuthorizationFactory 订阅时发出(例如,如果在 AuthorizationFactory 订阅之前解析了权限)。

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

关于Angular 2 APP_INITIALIZER 执行顺序/异步问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42572028/

相关文章:

angular - 如何正确使用 [ngStyle] 函数

angular - 用作 PartialObserver 的 BehaviorSubject 打破了对 BehaviorSubject 的订阅

angular - 在非 ES5 类 : expected TranslateFakeLoader to have an inner class declaration 上调用 getInternalNameOfClass() 中的错误

javascript - 并排显示两个输入

javascript - 获取当前 URL 会给出 Router 的静态注入(inject)器错误

Angular 5 : Dynamic component loading - StaticInjector error with @angular/core dependencies

angular - 带有angular-cli的angular2中环境特定的服务端点

javascript - 使用 Angular2 上传文件

angular - 使用 RxJS forkJoin 时传递参数的最佳方法

node.js - 如何在node.js后端和Angular 2前端中使用jwt实现社交登录