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

Wait for multiple http requests to finish before running a function in angular

我有多个 http posts 从 MySQL 数据库中获取 JSON 数据。我想要一个函数来监听所有这些,运行 下一段代码,一旦它们都返回数据已收到。

我尝试了多种带有 await 的异步变体,但该函数似乎没有等待 HTTP post 完成。

我有一个风险服务 risk.service.ts 来获取风险表,例如:

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 倍的变化来让它工作我正在慢慢失去我的香蕉!

既然你正在使用 Angular,你应该使用 RxJS 的 forkJoin to combine the observables from both api request methods into a single value observable, and return the values by 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() 其中 returns 它们作为一个 Promise。

首先,async/await 关键字用于承诺,而不是 Observable。所以你可以使用 toPromise() 将 observable 转换为 promise,或者你可以使用 rxjs ForkJoin。您还需要将方法更改为 return observable 或 return promise,您不能对 Subscription 做太多事情,这就是您调用时的 subscribe returns这就是你现在从 getRiskTable.

传递的内容

另一个问题是你没有利用类型系统,不要到处使用 any 因为这些错误可能在转译时被捕获,现在你必须猜测为什么它在 运行 比较难的时候

import { forkJoin } from 'rxjs';
import { shareReplay } from 'rxjs/operators';

getRiskTable() : Observable<Risk[]> {
  const tableObservable = this.riskService.getRiskTable().pipe(shareReplay());
  tableObservable.subscribe((res) => this.riskTable = res, (err) => {this.error = err;});
  return tableObservable;
}

getAllData() {
  let riskTable = this.getRiskTable();
  let risks = this.getAllRisks(); // should also return some observable

  forkJoin(riskTable, risks).subscribe(_ => {
    // all observables have been completed
  });
}

请注意,我还添加了 shareReplay 以确保对同一可观察对象的多个订阅不会导致对 API 端点的多次调用。一个结果在 observable 的多个订阅之间共享。

你的第一个函数 getRisk return是一个可观察的而不是一个承诺,你需要做一个 .toPromise() 来将你的可观察的转换为承诺。 你的第二个函数 getRiskTable 订阅了与你的第一个函数相比非常不一致的可观察对象,你应该像你的第一个函数一样做 return 一个承诺然后你的异步等待应该工作。

或者您可以使用 forkjoin(obs1,obs2),取决于您的兴趣,但请保持一致。