【问题标题】:Wait for providers constructor to be ready before using it在使用之前等待提供者构造函数准备好
【发布时间】:2018-08-13 08:30:16
【问题描述】:

在我的应用程序中,我使用一个提供程序进行身份验证,一个提供程序用于加载应用程序配置文件。不过,auth 提供程序使用来自config 提供程序的数据。所以我希望auth 提供者等待config 提供者构造函数准备好,然后再调用它的getSelectedConfig() 方法。现在我实现了以下机制

// AuthProvider
@Injectable()
export class AuthProvider {

  private url:string;
  private token:string;

  constructor(
    public http: HttpClient,
    public config: ConfigProvider
  ) { 
    this.loadParams();
  }

  private loadParams() {
    this.config.ready().subscribe(
      ready => {
        this.config.getSelectedConfig().subscribe(
          config => { 
            this.url = config.endpoint;
            this.token = config.token;
          }
        );
      }
    )
  } 
}

// ConfigProvider (in seperate file, of course)
@Injectable()
export class ConfigProvider {

  private selectedConfig:Config = null;
  private configStorageKey:string = "selected_config";
  public readyObservable:Observable<boolean>;

  constructor(
      public storage: Storage,
      public http: HttpClient
    ) {
    this.checkStorageForConfig();
  }

  public ready(){
    return this.readyObservable;
  }

  public checkStorageForConfig() {
    this.readyObservable = Observable.create(
      observer => {
        this.storage.get(this.configStorageKey).then(
          config => {
            if(config){
              this.selectedConfig = config;
            }
            observer.next();
          }
        )
      }
    )
  }
}

所以我创建了一个可以提供给auth 的 Observable,以了解是否已经可以使用 config 提供程序。

此方法有效,但我认为这不是一个好的解决方案。然而我想不出更好的。我一般不知道如何处理这种情况。

在我看来,我想简单地调用 this.config.ready().then( ... ) 之类的东西,而不引入其他 Observable。但也许这毕竟是正确的方法。

【问题讨论】:

  • 查看 APP_INITIALIZER 以在应用加载之前加载您的配置服务

标签: angular typescript asynchronous ionic-framework storage


【解决方案1】:

您可以通过使用 await async/await 来简化它,如果逻辑开始进一步增加,我建议您使用单独的服务来处理 onReady 问题。这只是一个简单的返工:

// AuthProvider
@Injectable()
export class AuthProvider {

private url: string;
private token: string;

constructor(
    public http: HttpClient,
    public config: ConfigProvider
) {
    this.loadParams();
}

private loadParams() {
    this.config.readyObservable.subscribe(
        ready => {
            if (ready) {
                this.config.getSelectedConfig().subscribe(
                    config => {
                        this.url = config.endpoint;
                        this.token = config.token;
                    }
                );
            }
        }
    )
}

// ConfigProvider (in seperate file, of course)

@Injectable()
export class ConfigProvider {

private selectedConfig: Config = null;
private configStorageKey: string = "selected_config";
public readyObservable: ReplaySubject<boolean> = new 
ReplaySubject(1);

constructor(
    public storage: Storage,
    public http: HttpClient
) {
    waitForStuffInConstructor()
}

public ready() {
    return this.readyObservable;
}
public async waitForStuffInConstructor() {
    await this.checkStorageForConfig();
    this.readyObservable.next(true);
}
public checkStorageForConfig() {
    this.storage.get(this.configStorageKey).then(
        config => {
            if (config) {
                this.selectedConfig = config;
            }
            observer.next();
        }
    )
}

【讨论】:

  • 这看起来很有帮助,但是我的readyObservable似乎没有.next()的方法?
  • 也没有调用waitForStuffInConstructor,不过我猜应该是在构造函数中调用吧?
  • 对不起,因为我在工作,所以在回答时很匆忙,我已经对其进行了一些编辑,以便您使用仅在给出 next() 值时才会发出的重播主题。是的,您在构造函数中调用 waitForStuffInConstructor() 。希望这会有所帮助。
  • 是的,这很合理。谢谢你。我对离子/角度的开发相当陌生。这样做实际上是一种好的做法还是有更好的方法?
  • 我认为作为服务之间的一种通信方法,它绝对没问题。这也很棒,因为您可以使用 Observable 监控配置中的更改并根据它进行更改。
猜你喜欢
  • 2015-03-31
  • 1970-01-01
  • 2019-04-05
  • 1970-01-01
  • 2021-04-26
  • 1970-01-01
  • 2020-06-21
  • 2013-12-24
  • 1970-01-01
相关资源
最近更新 更多