繁体   English   中英

在 Angular rxjs 中订阅

[英]Subscribe in subscribe in Angular rxjs

我有:

getSth(): void {
    this.service.functionName.pipe(
      takeUntil(this.destroy$),
      distinctUntilChanged(),
      map(res => res.event)
    ).subscribe(((response) => {
      this.getAnother(response);
    }));   }

getAnother(response): void {
    this.anotherService.anotherFunctionName(response).subscribe((res) => {
      this.result = res;
    });   }

我知道在订阅中编写订阅不是一个好的解决方案。 如何解决?

让我们使用switchMap

getSth(): void {
  this.service.functionName.pipe(
    takeUntil(this.destroy$),
    distinctUntilChanged(),
    map(res => res.event),
    switchMap(response =>
      this.anotherService.anotherFunctionName(response)
    )
  ).subscribe(response => this.result = response);
}

您应该尽可能地将 observable 链接在一起,在顶层只有一个订阅者。 对此有很多很好的理由,超出了本答案的范围。

您可以重构您的代码以从您的函数返回一个 observable(使用tap执行任何副作用,例如更新状态),并使用switchMap将其链接到现有的 observable。

getSth(): void {
    this.service.functionName.pipe(
      takeUntil(this.destroy$),
      distinctUntilChanged(),
      map(res => res.event),
      switchMap(response => this.getAnother(response))
    ).subscribe();   
}

// TODO: return correct type in Observable<T>
getAnother(response): Observable<any> {
  return this.anotherService.anotherFunctionName(response).pipe(
    tap(res => this.result = res)
  );   
}

你有更多的选择,有一些*map操作符,它们以不同的方式处理流。 通过您的示例,您可以使用switchMap ,它取消您正在运行的可观察对象(在您的示例中为getAnother )。 文档中有一个Operator Decision Tree ,试试看,它很有帮助。

您可以使用以下逻辑获得switchMap

  1. 我有一个现有的 Observable,并且
  2. 我想为每个值启动一个新的 Observable
  3. 并在新值到达时取消之前嵌套的 Observable
  4. 其中为每个值计算嵌套的 Observable

另一个注意事项,您应该将takeUntil放在最后。

你可以这样写:

getSth(): void {
  this.service.functionName.pipe(
    // If service.functionName returns a new object every time distinctUntilChanged will do nothing as references won't be the same.
    // distinctUntilChanged(),
    switchMap(resp => this.anotherService.anotherFunctionName(resp.event))
    takeUntil(this.destroy$),
    ).subscribe((result) => {
      this.result = result;
    }));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM