我有多个http帖子,它们从MySQL数据库中获取JSON数据。我希望有一个函数可以监听所有这些函数,并在它们全部返回已接收到数据后运行下一段代码。
我尝试使用await进行异步的多种变体,但是该功能似乎没有等待HTTP发布完成。
我有一个风险服务risk.service.ts来获取例如RiskTable:
getRiskTable(): Observable<Risk[]> {
return this.http.get(`${this.baseUrl}/getRiskTable`).pipe(
map((res) => {
this.riskTable = res['data'];
return this.riskTable;
}),
catchError(this.handleError));
}
在我的仪表板上,我将此代码称为:
getRiskTable():any {
return this.riskService.getRiskTable().subscribe(
(res: []) => {
this.riskTable = res; // the value is correctly captured here
return true;
},
(err) => {
this.error = err;
}
);
}
然后是运行多个这些功能的异步功能,从理论上讲,它要等到所有功能完成后再记录值。但是由于某些原因,此函数未定义全局变量this.riskTable。
async getAllData(){
let riskTable = await this.getRiskTable();
let risks = await this.getAllRisks();
console.log(riskTable); //This returns stuff
console.log(risks);
console.log(this.riskTable); //This returns undefined even though it was set in getRiskTable
}
请任何指针-我对angular还是很陌生,而它的复杂性使我完全迷住了。 2天和100倍变化才能使它正常工作,我正在慢慢失去香蕉!
答案 0 :(得分:1)
由于您正在使用Angular,因此应该使用RxJS的forkJoin将来自两个api请求方法的可观察值组合为一个可观察值,然后将subscribing的值返回给它。
请记住将forkJoin
导入组件。
import { forkJoin } from 'rxjs';
..
getAllData(){
const riskTable = this.riskService.getRiskTable();
const risks = this.riskService.getAllRisk();
forkJoin(riskTable, risks).subscribe(response => {
console.log(response);
})
}
如果您坚持将其作为Promise处理而不是将其作为Observable处理,则可以利用Promise.all()将其作为单个Promise返回。
答案 1 :(得分:1)
首先,async
/ await
关键字用于promise,而不用于Observable
。因此,您可以使用toPromise()
将可观察对象转换为Promise,也可以使用rxjs ForkJoin。您还需要更改方法以返回可观察的结果或返回承诺,您无法对Subscription进行太多操作,Subscription是您调用subscribe
时返回的内容,而这正是您从{{1 }}。
另一个问题是您没有利用类型系统,不要在各处使用getRiskTable
,因为这些错误可能在转换时就被捕获了,现在您必须猜测为什么它在运行时会失败,更困难。
any
请注意,我还添加了shareReplay
,以确保对同一可观察对象的多次订阅不会导致对API端点的多次调用。一种结果是在可观察对象的多个订阅之间共享。
答案 2 :(得分:0)
您的第一个函数getRisk返回可观察到的而不是诺言,您需要执行.toPromise()将可观察到的转变成诺言。 您的第二个函数getRiskTable预订了可观察对象,与第一个函数相比,这是非常不一致的,您应该执行相同的操作,因为第一个函数只返回一个promise,然后异步等待就可以工作。
或者您可以使用forkjoin(obs1,obs2),具体取决于您的兴趣,但保持一致。