【问题标题】:Typescript transform forkJoin results with pipe and cleanupTypescript 使用管道和清理转换 forkJoin 结果
【发布时间】:2020-10-17 07:35:02
【问题描述】:

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().subscribe() 的结果存储在 Subscription 中并在组件被销毁时手动取消订阅? dependencyServicemicroserviceService 在我的例子中只是包装 http:

  query(req?: any): Observable<EntityArrayResponseType> {
    const options = createRequestOption(req);
    return this.http.get<IDependency[]>(this.resourceUrl, { params: options, observe: 'response' });
  }

完整的源代码可用here

【问题讨论】:

    标签: angular typescript rxjs


    【解决方案1】:

    这只是一点点重构。您可以在 query() 方法内转换数据,也可以在 loadAll() 方法内转换数据。

    以下是您可以重写 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 的任何内部 observables 出现错误,您将失去任何其他将或已经完成的 observables 的值。 所以最好正确处理错误。您可以像这样捕获错误并返回一个空数组。

     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 服务创建的。看到这个post。一旦所有内部可观察对象完成,forkJoin 将自动完成。我希望这会有所帮助。

    【讨论】:

    • 谢谢先生,它真的很有帮助!我不确定现在如何将两个答案合并为一个,因为我早一点回答了自己,Michael 的 cmets 也有助于理解这个特定的用例
    • @tillias 正如我所说,这只是解决方案之一,而不是唯一的解决方案。我只是试图解释你问题的所有部分。您可以将任何适合您的答案标记为已接受。
    【解决方案2】:

    感谢article,有两种可能性

    使用 zip():

      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);
        });
      }
    

    或使用 forkJoin()

      loadAll(): void {
        const dependencies$ = this.dependencyService.query();
        const microservices$ = this.microserviceService.query();
    
        forkJoin({dependencies$, microservices$})
          .pipe(
            map(result => {
                return {
                  dependencies: result.dependencies$.body || [],
                  microservices: result.microservices$.body || []
                }
              }
            )
          )
          .subscribe(results => {
            this.refreshGraph(results.dependencies, results.microservices);
          });
      }
    

    在这种特殊情况下,两者的工作方式相同,因为源 observable 只会发射一次(请参阅来自 Michael D 的 cmets)

    您不需要取消订阅,因为 httpfinite observable 另请参阅 this answer

    【讨论】:

    • 1)。可以跳过取消订阅,不是因为它很冷,而是因为来自 Angular HttpClient 的 observable 在单次发射后完成。但是如果请求从未发出并且没有其他方法可以完成(例如使用timeout),它仍然可能会挂在那里。
    • 2)。 zipforkJoin(和 combineLatest 就此而言)不一样。 forkJoin 只会发出一次并在所有源 observables 完成时完成。 zipcombineLatest 更适合数据流。 zip 将在 每个 可观察对象发出一次时发出,combineLatest 将在 任何 可观察对象发出时发出。也是最小鬼。 zipcombineLatest 都只会在所有源 obs 之后开始发射。至少发射过一次。
    • 感谢 Michael,将其固定为“有限”可观察并提供了附加链接。关于 zip 和 forkJoin -> 因为 http 在这里是有限的并且总是完整的,我认为调用哪一个并不重要?还是你觉得 forkJoin() 在这里更合适?
    • 是的,但仅限于像这样的特定情况(源 observable 只会发出一次)。这也需要提及。目前答案只说明两者的工作方式相同
    • 太好了,非常感谢 -> 已修复。现在这看起来像是一个完美的答案?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    • 2021-03-09
    • 2019-03-05
    • 2019-11-14
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    相关资源
    最近更新 更多