在使用它之前等待提供者构造函数准备就绪
Wait for providers constructor to be ready before using it
在我的应用程序中,我使用一个提供程序进行身份验证,并使用一个提供程序加载应用程序配置文件。不过,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。但也许这毕竟是正确的方法。
您可以通过使用 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();
}
)
}
在我的应用程序中,我使用一个提供程序进行身份验证,并使用一个提供程序加载应用程序配置文件。不过,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。但也许这毕竟是正确的方法。
您可以通过使用 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();
}
)
}