Angular Typescript转换forkJoin结果与管道和清理

Angular Typescript转换forkJoin结果与管道和清理,angular,typescript,rxjs,Angular,Typescript,Rxjs,转换forkJoin()结果的最佳方法是什么?因此,在subscribe()方法中,我可以这样写: this.refreshGraph(dependencies,microservices); 以下是它目前的工作原理: loadAll(): void { const dependencies = this.dependencyService.query(); const microservices = this.microserviceService.query();

转换forkJoin()结果的最佳方法是什么?因此,在subscribe()方法中,我可以这样写:

this.refreshGraph(dependencies,microservices);
以下是它目前的工作原理:

  loadAll(): void {
    const dependencies = this.dependencyService.query();
    const microservices = this.microserviceService.query();


    forkJoin({dependencies, microservices})
      .subscribe(results => {
        this.refreshGraph(results.dependencies.body || [], results.microservices.body || []);
      });
  }

  refreshGraph(dependencies: IDependency[], microservices: IMicroservice[]): void {
  ...
  }
我是否需要在订阅中存储forkJoin()。订阅()的结果,并在组件销毁时手动取消订阅?在我的例子中,dependencyService和microserviceService只需包装http

  query(req?: any): Observable<EntityArrayResponseType> {
    const options = createRequestOption(req);
    return this.http.get<IDependency[]>(this.resourceUrl, { params: options, observe: 'response' });
  }
  loadAll(): void {
    zip(this.dependencyService.query(), this.microserviceService.query())
      .pipe(
        map(([dependencyResponse, microserviceResponse]) => {
          return {
            dependencies: dependencyResponse.body || [],
            microservices: microserviceResponse.body || []
          }
        })
      ).subscribe(results => {
      this.refreshGraph(results.dependencies, results.microservices);
    });
  }
查询(请求?:任何):可观察{
常量选项=createRequestOption(req);
返回this.http.get(this.resourceUrl,{params:options,observe:'response'});
}

完整的源代码可用

多亏了这一点,有两种可能

使用zip():

或使用forkJoin()

在这种特殊情况下,这两种方法的工作原理相同,因为SourceObservable只会发出一次(请参阅中的注释)


您不需要取消订阅,因为http也可以参见这只是一点点重构。您可以在
query()
方法中转换数据,也可以在
loadAll()方法中转换数据

 loadAll(): void {
    const dependencies = this.dependencyService.query().pipe(map(result => result.body || []));
    const microservices = this.microserviceService.query().pipe(map(result => result.body || []));;


    forkJoin({dependencies, microservices}).subscribe(
       ({dependencies, microservices}) => this.refreshGraph(dependencies,microservices)
    );
  }
下面是重写
loadAll()
方法的方法之一

 loadAll(): void {
    const dependencies = this.dependencyService.query().pipe(map(result => result.body || []));
    const microservices = this.microserviceService.query().pipe(map(result => result.body || []));;


    forkJoin({dependencies, microservices}).subscribe(
       ({dependencies, microservices}) => this.refreshGraph(dependencies,microservices)
    );
  }
请记住,如果提供给forkJoin的任何内部观察值出现错误,那么您将丢失任何其他可能或已经完成的观察值。 因此,最好正确处理错误。您可以捕获错误并返回如下所示的空数组

 const dependencies = this.dependencyService.query().pipe(
  map(result => result.body || []),
  catchError(() => of ([]))
);
const microservices = this.microserviceService.query().pipe(
  map(result => result.body || []),
  catchError(() => of ([]))
);

此外,您不需要在这里手动取消订阅,因为observable是由angular的httpClient服务创建的。看这个。一旦所有内部观测完成,forkJoin将自动完成。我希望这会有所帮助。

1)。取消订阅可以跳过,不是因为天气冷,而是因为HttpClient在一次发射后就完成了观测。但是,如果请求从未发出,并且没有其他方法可以完成(例如使用
超时
),那么它仍然可能挂在那里
zip
forkJoin
(和
combinelatetest
)不一样
forkJoin
将仅发出一次,并在所有源观测完成时完成
zip
combinelateest
更适合于数据流
zip
将在每个可观测对象发射一次时发射,而
combinelateest
将在任何可观测对象发射时发射。此外,大多数imp.
zip
CombineTest
仅在所有源OB之后才开始发射。至少发射过一次。谢谢Michael,修复了“有限”可观测并提供了额外链接。关于zip和forkJoin->由于http在这里是有限的并且总是完整的,我认为调用哪个并不重要?或者您认为forkJoin()在这里更合适吗?是的,但仅在像这样的特定情况下(源可观测对象只发射一次)。这也需要提到。目前的答案只是说明两者工作相同。太好了,非常感谢->修复。这看起来是个完美的答案?谢谢,先生,真的很有帮助!我不知道现在如何将两个答案合并成一个原因,因为我刚才回答了自己,Michael的评论也有助于理解这个特殊用法-case@tillias正如我所说,这只是解决方案之一,而不是唯一的解决方案。我只是试着解释你问题的所有部分。您可以将任何对您有效的答案标记为已接受。