Angular 2 APP_INITIALIZER执行顺序/异步问题 [英] Angular 2 APP_INITIALIZER Execution order / async issue

查看:158
本文介绍了Angular 2 APP_INITIALIZER执行顺序/异步问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've got 2 APP_INITIALIZER providers... the first makes an HTTP request to get environment information.

第二个命令使用环境信息根据OIDC授权服务器端点(从环境调用获得)授权用户.

The second uses the environment info to authorize the user against an OIDC Authority server endpoint (obtained from environment call).

看起来,尽管使环境服务成为授权服务的依赖项,但在完成环境调用之前,会调用授权服务的APP_INITIALIZER工厂功能.

It seems like, despite making the environment service a dependency of the authorization service, the authorization service's APP_INITIALIZER factory function is called before the environment call is completed.

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

提供给APP_INITIALIZER的两个工厂都具有签名:

Both factories provided to APP_INITIALIZER are of the signature:

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

结果是授权调用提交到undefined而不是正确的URL.

The result is that the authorization call submits to undefined instead of a proper URL.

我曾经考虑过合并工厂-但是它们位于两个不同的模块中,因此感觉很混乱.指导表示赞赏!

I've thought of combining the factories - but they are in two different modules so it feels messy. Guidance appreciated!

推荐答案

我最终将解决的EnvironmentProvider注入到AuthorizationFactory中.

I ended up injecting the resolved EnvironmentProvider into the AuthorizationFactory.

我向EnvironmentProvider添加了一个Observable,它在Authority值更改时发出.

I added an observable to the EnvironmentProvider that emits any time the Authority value changes.

{ 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订阅之前已解决颁发机构).

I use a ReplaySubject(1) as the source for env.Authority$(). This ensures that the observable returned always emits upon subscription by the AuthorizationFactory (e.g. if the Authority was resolved prior to the AuthorizationFactory subscribing).

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

Anyone who comes across this wondering why I'm not using toPromise()... I think there is some issue (I've submitted for review here). https://github.com/Reactive-Extensions/RxJS/issues/1429

这篇关于Angular 2 APP_INITIALIZER执行顺序/异步问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆