在以角度运行函数之前等待多个 http 请求完成

Bre*_*cht 3 asynchronous listener angular

我有多个从 MySQL 数据库中获取 JSON 数据的 http 帖子。我想要一个函数来侦听所有这些,并在所有这些都返回已收到数据后运行下一段代码。

我已经尝试了使用 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));
  }
Run Code Online (Sandbox Code Playgroud)

在我的仪表板上,我调用此代码:

getRiskTable():any {
    return this.riskService.getRiskTable().subscribe(
      (res: []) => {
        this.riskTable = res; // the value is correctly captured here
        return true;
      },
      (err) => {
        this.error = err;
      }
    );
  }
Run Code Online (Sandbox Code Playgroud)

然后是一个运行多个这些函数的异步函数,理论上它应该等到所有函数完成然后记录值。但是由于某种原因,全局变量 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
  }
Run Code Online (Sandbox Code Playgroud)

请指点 - 我对 angular 很陌生,它的复杂性让我完全被难住了。2 天和 100 倍的变化才能让它发挥作用我正在慢慢失去我的香蕉!

Igo*_*gor 6

首先async/await关键字用于 promises,而不是Observables。因此,您可以使用toPromise()或使用 rxjs ForkJoin将 observable 转换为承诺。您还需要更改方法以返回 observable 或返回承诺,您不能对 Subscription 做太多事情,这是subscribe您调用它时返回的内容,这就是您现在从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
  });
}
Run Code Online (Sandbox Code Playgroud)

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