簡體   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