Angular 异步请求没有及时加载

Angular asynchronous request not loaded in time

我在 Angular 中尝试执行一个棘手的异步请求时遇到了一些问题。我正在显示一个用户界面,其中包含浓缩在 table 中的特定信息。 table 包含使用 HttpClient 模块提供的 http.get 方法从后端加载的 headers。我在ngOnInit()方法中调用这个方法。偶尔会出现 table 的 headers 在显示 table 之前未加载的情况。如何避免这个问题?

实现的一些信息:

ngOnInit(): void {
    this.toastService.reset();
    this.load();
  }

  load(): void {
    const workflows = this.getWorkflows();
    const headers = this.getHeaders();

    forkJoin([workflows, headers]).subscribe((results) => {
      this.setWorkflows(results[0]);
      this.setHeaders(results[1]);
    }, (error) => {
      console.error(`error = ${error}`);
    });
  }

  getWorkflows(): Observable<VisibleWorkflow[]> {
    return this.workflowService.getWorkflows().pipe(
      map((response) => {
        return this.workflows = response;
      })
    );
  }

  setWorkflows(workflows: VisibleWorkflow[]): void {
    this.workflows = workflows.map((workflow) => {
      return {...workflow};
    });
  }

  getHeaders(): Observable<VisibleHeader[]> {
    return this.headerService.getHeaders().pipe(
      map((response) => {
        return this.headers = response;
      })
    );
  }

  setHeaders(headers: VisibleHeader[]): void {
    this.headers = headers;
  }

感谢您的宝贵时间!

您可以使用 combineLatest

combineLatest:每当任何输入 Observable 发出一个值时,它都会使用所有输入的最新值计算一个公式,然后发出该公式的输出。 https://rxjs.dev/api/index/function/combineLatest

您遇到的问题是因为您将值分配给 this.workflowsthis.headers 两次。首先,您在 RxJS.map 运算符内部分配一个值,然后在 forkJoin.

的订阅中分配一个值

由于 forkJoin 仅在每个 Observable 完成后立即发出值,因此您应该仅在订阅中而不是在 RxJS.map 中分配值。

因此,您的代码如下所示:

load(): void {
  const workflows = this.getWorkflows();
  const headers = this.getHeaders();

  forkJoin([workflows, headers]).subscribe(
    // I used array deconstruction here because I prefer that over hard coded indexes
    ([wfs, heads]) => {
      this.setWorkflows(wfs);
      this.setHeaders(heads);
    }, 
    (error) => {
      console.error(`error = ${error}`);
    }
  );
}

getWorkflows(): Observable<VisibleWorkflow[]> {
  return this.workflowService.getWorkflows();
}

getHeaders(): Observable<VisibleHeader[]> {
  return this.headerService.getHeaders();
}

像这样,您只是在两个请求都完成后才分配值,因此您应该不会再有时间问题了。

只要两个变量都没有设置,您也可以考虑隐藏您的 table:

<ng-container *ngIf="headers?.length && workflows">
  <!-- Your table here -->
</ng-container>

如果存在时间问题,这也可以解决 ;)