在Angular中运行函数之前,请等待多个http请求完成

时间:2019-04-25 18:38:33

标签: angular asynchronous listener

我有多个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倍变化才能使它正常工作,我正在慢慢失去香蕉!

3 个答案:

答案 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),具体取决于您的兴趣,但保持一致。