Angular - DialogRef - 取消订阅 - 我是否需要取消订阅 afterClosed?

liq*_*TAR 35 unsubscribe rxjs angular

我的一位同事问我是否需要取消订阅对话框的 afterClosed() Observable。

我们使用 takeUntil 模式取消订阅 ngOnDestroy() 上的所有 Observable。

this.backEvent = fromEvent(window, 'popstate')
    .pipe(
        takeUntil(this.destroy$)
    )
    .subscribe(
        () => {
            this.navigationService.backClicked = true;
            this.navigationService.navigateBackToDirectoryCenter();
        }
    );
Run Code Online (Sandbox Code Playgroud)

ngOnDestroy()

ngOnDestroy() {
    this.destroy$.next();
    this.destroy$.complete();
}
Run Code Online (Sandbox Code Playgroud)

那么是否有必要取消订阅 afterClosed() Observable 呢?

dialogRef.afterClosed().subscribe(
    (data) => {
            console.log(data);
        }
    },
);
Run Code Online (Sandbox Code Playgroud)

或者?

dialogRef.afterClosed()
    .pipe(
        takeUntil(this.destroy$)
    )
    .subscribe(
        (data) => {
            console.log(data);
        },
    );
Run Code Online (Sandbox Code Playgroud)

小智 67

你不需要在 observable 本身完成时取消订阅。你可以通过添加一个 finalize 块来验证它是否完成了 observable 本身。

import { finalize } from "rxjs/operators";
Run Code Online (Sandbox Code Playgroud)
dialogRef
  .afterClosed()
  .pipe(finalize(() => console.log("completed")))
  .subscribe(data => {
    console.log(data);
  });

Run Code Online (Sandbox Code Playgroud)

当您关闭对话框时,您将completed在控制台中看到,这表示您不需要取消订阅 observable。

  • 如果使用 switchMap 链接一些可观察量,它的工作方式是否相同? (2认同)

Sim*_*sen 9

当订阅块使用组件属性时,您通常希望取消订阅可观察量以防止内存泄漏并防止错误this.xxxx

即使订阅完成并且您不需要考虑内存泄漏,您也应该注意第二个问题。

dialogRef.afterClosed()当对话框仍然可见时,调用的主机组件可能会被销毁。订阅将在关闭后发出,当您访问订阅块内的组件属性时,它会抛出错误。

我认为这是一种罕见的情况,当对话框处于活动状态时主机组件被破坏,但我想指出这种边缘情况。一个例子是浮动按钮,它打开一个对话框,但在滚动或其他情况下消失。


小智 5

好问题,只需查看文档(https://material.angular.io/components/dialog/overview),似乎没有任何迹象表明需要取消订阅,您已经拥有的应该足够了。

  • 我认为文档没有涉及那么多细节,取消订阅可能根本超出了文档的范围。所以我不会依赖“如果文档中没有提到,那么就不需要”。 (4认同)