Angular 12:等待获取所有数据(forkjoin),然后再继续

4 typescript ecmascript-6 angular

在我的 ngOnInit 中,我想等待 fetchLists 的所有请求完成后再继续:

  ngOnInit(): void {
    this.fetchLists();

    this.route.params.subscribe(params => {
         this.doSomethingWithFetchedLists();
      }
    });
  }

  fetchLists(): void {
    this.httpHandlerCached.getListsA()
      .subscribe(listA => this.listA = listA);
    this.httpHandlerCached.getListsB()
      .subscribe(listB => this.listB = listB);
    this.httpHandlerCached.getListsC()
      .subscribe(listC => this.listC = listC);
  }

Run Code Online (Sandbox Code Playgroud)

请听我说完,我之前的问题已结束,并引用了使用“forkJoin”:等待多个承诺完成

然而,对于 forkjoin 我有完全相同的问题:

  fetchListnames() {
    return forkJoin([
      this.httpHandlerCached.getListsA(),
      this.httpHandlerCached.getListsB(),
      this.httpHandlerCached.getListsC(),
    ]).subscribe(res => {
        this.listA = res[0];
        this.listB = res[1];
        this.listC = res[2];
      });
  }

Run Code Online (Sandbox Code Playgroud)

因此,根据使用 forkJoin 的建议,我现在如何等待 forkjoin 完成后再继续(意思this.doSomethingWithFetchedLists()是调用 before )?

Sha*_*ham 6

不建议按照另一个答案的建议将订阅放在订阅中。相反,人们应该依赖 rxjs 管道并仅订阅一次。

在这种情况下,人们可能会认为放入this.route.params内部就forkJoin可以解决问题,但因为this.route.params永远不会完成,forkJoin所以不会发出(这就是forkJoin实现方式)。为了this.route.params完成,您可以将其通过管道传输到take(1),从而产生以下代码:

forkJoin([
      this.httpHandlerCached.getListsA(),
      this.httpHandlerCached.getListsB(),
      this.httpHandlerCached.getListsC(),
      this.route.params.pipe(take(1))
    ]).subscribe(res => {
        this.listA = res[0];
        this.listB = res[1];
        this.listC = res[2];
        this.doSomethingWithFetchedLists();
      });
Run Code Online (Sandbox Code Playgroud)

您还可以使用combineLatestnot forkJoin,它不会等待所有可观察量完成,而是每次其中一个可观察量发生变化时都会发出(但它将等待所有可观察量首先发出至少一个值)。

combineLatest([
          this.httpHandlerCached.getListsA(),
          this.httpHandlerCached.getListsB(),
          this.httpHandlerCached.getListsC(),
          this.route.params
        ]).subscribe(res => {
            this.listA = res[0];
            this.listB = res[1];
            this.listC = res[2];
            this.doSomethingWithFetchedLists();
          });
Run Code Online (Sandbox Code Playgroud)

如果您使用后一种方法,则必须手动取消订阅(或通过管道发送到take(1))。否则你会出现内存泄漏。


归档时间:

查看次数:

6609 次

最近记录:

3 年,11 月 前