gpt4 book ai didi

Angular 4如何等待httpclient完成

转载 作者:太空狗 更新时间:2023-10-29 17:33:32 27 4
gpt4 key购买 nike

在我的应用程序中,我有一些服务(正在调用其余服务)是从自定义基础服务继承的,该服务定义了在所有其他服务中使用的通用方法和属性。其中一个参数是我的休息服务的基本 url,它在环境下使用变量。但是现在要求使这个 url 来自配置文件。所以我必须使用 httpclient 来获取它,这提出了一个问题,现在在实际服务尝试使用基本 url 时它尚未解决。有没有办法等到那个电话解决?我的代码如下所示:

基础服务.service.ts:

export class BaseService{
protected apiUrlBase: string;

constructor(protected _http: HttpClient) {
// some logic

this.getConfigData()
.subscribe(
x => {
this.apiUrlBase = x.apiUrlBase;
}
);

}

getConfigData(): Observable<any> {
return this._http.get(
'../../assets/config.json'
)
.do(x => {
})
.catch(error => {
alert('Unable to read configuration file:' + JSON.stringify(error));
return Observable.throw(error);
});
}
}

一些数据.service.ts:

@Injectable()
export class TestService extends BaseApiService {
private get _someDataServiceUrl(): string {
return this.apiUrlBase + '/api/v1/somedata';
}

constructor(_http: HttpClient) {
super(_http);
}

getSomeData(): Observable<ISomeData[]> {
return this._http.get<ISomeData[]>(this._someDataServiceUrl)
.do(this.handleSuccessResponse)
.catch(this.handleErrorResponse);
}
}

关于我如何在我的服务中等待直到 apiUrl 得到解决的任何建议,或者我应该怎么做才能使用我的基本服务以及使用子服务所依赖的数据来解决直到他们使用它?

最佳答案

一个快速而肮脏的方法是使 URL 基本身成为可观察的,并确保服务中的任何内容都不能继续,直到它给出一个值:

export class BaseService{
protected apiUrlBase: BehaviorSubject<string> = new BehaviorSubject<string>(null);
protected apiUrlBase$: Observable<string> = this.apiUrlBase.filter(b => !!b).take(1);

constructor(protected _http: HttpClient) {
// some logic

this.getConfigData()
.subscribe(
x => {
this.apiUrlBase.next(x.apiUrlBase);
}
);

}

getConfigData(): Observable<any> {
return this._http.get(
'../../assets/config.json'
)
.do(x => {
})
.catch(error => {
alert('Unable to read configuration file:' + JSON.stringify(error));
return Observable.throw(error);
});
}
}


@Injectable()
export class TestService extends BaseApiService {
private _someDataServiceUrl(apiUrlBase): string {
return apiUrlBase + '/api/v1/somedata';
}

constructor(_http: HttpClient) {
super(_http);
}

getSomeData(): Observable<ISomeData[]> {
return this.apiUrlBase$.switchMap(apiUrlBase => this._http.get<ISomeData[]>(this._someDataServiceUrl(apiUrlBase))
.do(this.handleSuccessResponse)
.catch(this.handleErrorResponse));
}
}

但这显然非常难看。更好的解决方案是通过为它创建一个应用初始化程序提供程序来确保该基础服务在应用程序中的任何其他内容之前加载和解析:

import { Injectable, APP_INITIALIZER } from '@angular/core';

@Injectable()
export class BaseService{
protected apiUrlBase: string;

constructor(protected _http: HttpClient) {
}

getConfigData(): Observable<any> {
return this._http.get(
'../../assets/config.json'
)
.do(x => {
})
.catch(error => {
alert('Unable to read configuration file:' + JSON.stringify(error));
return Observable.throw(error);
});
}

public load() {
return new Promise((resolve, reject) => {
this.getConfigData()
.subscribe(
x => {
this.apiUrlBase = x.apiUrlBase;
resolve(true);
},
err => resolve(err)
);
});
}
}

export function BaseServiceInitFactory(baseService: BaseService) {
return () => baseService.load();
}

export const BaseServiceInitProvider = {
provide: APP_INITIALIZER,
useFactory: BaseServiceInitFactory,
deps: [BaseService],
multi: true
}

然后将 BaseServiceInitProvider 放在应用模块提供程序中的 BaseService 之后。

关于Angular 4如何等待httpclient完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47230418/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com