我是Angular的新手,我想做一个http get请求,根据它的响应,我必须做一个后端调用。
在这里,我试图链上2个异步调用,不知道这在Angular中是否是可行的正确方法(使用Angular 7版本)。
问题说明: 在得到第一个(http)async调用的响应之前,进行了第二次(后台)async调用。
我试过使用asyncawait(理解为不是正确的方法,但还是试过了)和在第一次http调用的订阅中调用后端调用。这两种方法都不成功。请让我知道这里出了什么问题,是否有更好的方法来链上2个异步调用。
以下是代码片段(简化版)。
export class BasicService{
let httpUrl:string=null;
constructor(protected http: HttpClient, protected backendSvc: BackendService) {
httpUrl='/someUrl';
}
getComponentData(route: ActivatedRoute): Observable<ComponentData> {
let callName:string;
let inputPayload:string;
let routeID=route.snapshot.url[0].path;
if (routeID.Equals('Test')) {
callName='TestCall';
}
else if (routeID.Equals('Execute')) {
callName='ExecuteCall';
}
//Failure#1: Get http response back and then call backendSvc, inputPayload remains empty
//want to wait for _waitCreateInputPayload to finish execution before calling backendSvc
inputPayload = this._waitCreateInputPayload(httpUrl,callName);
//backendSvc returns an observable
return this.backendSvc.GetData(callName, inputPayload, null, this.FormFactorType);
//Failure#2: This approach also doesn't work.
this._createInputPayload(httpUrl,callName).subscribe(tempVal=>{
if(tempVal!=undefined){
return this.backendSvc.GetData(callName, tempVal, null, this.FormFactorType);
}else{
return null;
}
});
}
private async _waitCreateInputPayload(httpUrl: string, callName:string){
return await this.http.get(httpUrl, { responseType: 'text' }).subscribe(tempVal=>{
console.log('in _createInputPayload');
return tempVal;
});
}
private _createInputPayload(httpUrl: string, callName:string): string{
return this.http.get(httpUrl, { responseType: 'text' });
}
}
组件的代码是这样的。
export class ChildTemplateComponent implements OnInit {
constructor(protected basicSvc: BasicService, protected route: ActivatedRoute) {}
ngOnInit() {
this.formFactorSvc = this.route.snapshot.data['formFactor'];
this.formFactorSvc.getDesignConfig(this.route);
}
ngInit() {
this.basicSvc.getComponentData(this.route).subscribe((x) => {
this.populateData(x);
});
}
populateData(data: ComponentData){
//populate the View
}
}
谢谢你
RDV
使用RxJs可以将_createInputPayload的返回结果用管道传送,在管道中可以将_createInputPayload的结果打入一个成员变量,然后mergeMap会调用GetData。当你从组件中订阅getComponentData时,由于那是最后一个mergeMap,所以订阅将是GetData。
return this._createInputPayload(this.httpUrl, callName).pipe(
tap((input) => inputPayload = input),
mergeMap(() => this.backendSvc.GetData(callName, inputPayload, null, this.FormFactorType)));
_createInputPayload应该返回一个Obseravble而不是字符串,因为http.get返回的是一个Observable。一旦你改变了这一点,你就可以订阅它,然后在进行后台调用之前,你会得到http响应。