繁体   English   中英

Angular 6 - 在依赖注入之前使用异步调用初始化服务

[英]Angular 6 - Initialize service with async calls before dependency injection

我有一个基于环境文件的服务,在内存中加载一个配置对象。 但是,设置的读取是异步的,应用程序甚至在所有设置都加载和崩溃之前就启动了。 在依赖注入完成之前,有什么方法可以“等待”这些函数。

我的服务:

import { Injectable } from '@angular/core';
import { IAppConfig } from '../models/app-config.model';

@Injectable()
export class AppConfig {
    settings: IAppConfig;
    version: any;

constructor() {
    this.loadConfig();
}

// reads env.json file
// based on which environment it is loads config setting from
// environment specific config settings.

public loadConfig() {
    return new Promise((resolve, reject) => {
        const envFile = '/env.json';
        this.readJsonFile(envFile).
            then((envData) => {
                const configFile = `assets/appconfigs/config.${envData.env}.json`;
                this.version = envData.version;
                this.readJsonFile(configFile).
                    then((configsettings) => {
                        this.settings = configsettings;
                        resolve(this.settings);
                    });
            });
    });
}

// reads json file and returns the json object promise
public readJsonFile(jsonUrl: string): any {
    return new Promise((resolve, reject) => {
        let retObject: any;
        const xhr = new XMLHttpRequest();
        xhr.overrideMimeType('application/json');
        xhr.open('GET', jsonUrl, true);
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    retObject = JSON.parse(xhr.responseText);
                    resolve(retObject);
                } else {
                    reject(`Could not load file '${jsonUrl}': ${xhr.status}`);
                }
            }
        };
        xhr.send(null);
    });
}

}

我希望在应用程序启动之前加载设置对象。 另一种方法是使这个类静态并调用 loadConfig 但这对测试平台来说是一场噩梦。 在模块中提供服务时有什么我可以指定的吗?

我不确定这个解决方案(未经测试的代码),但是我想您可以async/await一切。

有什么理由不使用Angular的http服务,而是使用手动XMLHttpRequest吗?

可能是这样的:

constructor() {
    this.run()
}

async run() {
    await this.loadConfig()
}

// reads env.json file
// based on which environment it is loads config setting from
// environment specific config settings.

public loadConfig() {
    return new Promise( async (resolve, reject) => {
        const envFile = '/env.json';

        let envData = await this.readJsonFile(envFile)

        const configFile = `assets/appconfigs/config.${envData.env}.json`;

        this.version = envData.version;

        this.settings = await this.readJsonFile(configFile);

        resolve(); // No need to pass this.settings to resolve()
    });
}

// reads json file and returns the json object promise
public readJsonFile(jsonUrl: string): any {
    return this.http
        .get(jsonUrl)
        .map(res => res.json())
        .toPromise()
}

我希望在应用程序启动之前加载设置对象。

您可以/应该使用注入令牌 APP_INITIALIZER: angular.io/APP_INITIALIZER

在你的情况下,像下面的代码就足够了。 在您的 AppModule 中:

{
  provide: APP_INITIALIZER,
  useFactory: initApp,
  deps: [//add here services which depend on app-config
  ],
  multi: true
}

export function initApp(appConfig: AppConfig) {
  return () => appConfig.loadConfig();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM