七爪源码:Angular:销毁时自动取消订阅 Observables

永远不要写另一个 ngOnDestroy 来清理你的订阅

七爪源码:Angular:销毁时自动取消订阅 Observables

使用 Angular 时真正让我烦恼的一件事是,我必须保存我所有的订阅,才能在 ngOnDestroy 上取消订阅。

这太烦人了,我必须到处这样做。 我已经搜索了解决方案,但所有这些都涉及声明 ngOnDestroy,我不希望这样。

我只想订阅一些东西并告诉 Angular 在组件被销毁时自动取消订阅。

然而,我已经意识到,我可以通过将 ngOnDestroy 委托给一个服务来实现我想要的,这让我非常兴奋! 自从 Angular 2 发布以来,这一直是我的痛点。


每个组件的服务

通过在组件中提供服务,它的存在变得依赖于组件。

当组件被销毁时,服务也被销毁。 我会给你看:

在您的组件中提供服务,将其注入构造函数并在服务和组件中发生 ngOnDestroy() 时记录。

@Injectable()
export class UnsubscriberService implements OnDestroy {
  public ngOnDestroy(): void {
    console.log('service on destroy');
  }
}
@Component({
  selector: 'app-test',
  template: 'test',
  providers: [UnsubscriberService]
})
export class TestComponent implements OnDestroy {
  constructor(private readonly _unsubscriber: UnsubscriberService) {}
  public ngOnDestroy(): void {
    console.log('component on destroy');
  }
}

您会看到服务在组件之前被销毁。


直到服务销毁

知道我们可以创建一个在服务被销毁时发出的 observable,并在发生这种情况时使用 takeUntil() 自动取消订阅。

@Injectable()
export class UnsubscriberService implements OnDestroy {
  private readonly _destroy$ = new Subject();
  public readonly destroy$ = this._destroy$.asObservable();
  public ngOnDestroy(): void {
    this._destroy$.next();
    this._destroy$.complete();
  }
}
@Component({
  selector: 'app-test',
  template: 'test',
  providers: [UnsubscriberService]
})
export class TestComponent implements OnInit {
  constructor(private readonly _unsubscriber: UnsubscriberService) {}
  public ngOnInit(): void {
    timer(0, 500)
      .pipe(takeUntil(this._unsubscriber.destroy$))
      .subscribe((x) => console.log(x));
  }
}

为简化起见,我们可以将 takeUntil() 逻辑放在我们的服务中,并通过一个简单的方法将其公开。

@Injectable()
export class UnsubscriberService implements OnDestroy {
  private readonly _destroy$ = new Subject();
  public readonly takeUntilDestroy = (
    origin: Observable
  ): Observable => origin.pipe(takeUntil(this._destroy$));
  public ngOnDestroy(): void {
    this._destroy$.next();
    this._destroy$.complete();
  }
}
@Component({
  selector: 'app-test',
  template: 'test',
  providers: [UnsubscriberService]
})
export class TestComponent implements OnInit {
  constructor(private readonly _unsubscriber: UnsubscriberService) {}
  public ngOnInit(): void {
    timer(0, 500)
      .pipe(this._unsubscriber.takeUntilDestroy)
      .subscribe((x) => console.log(x));
  }
}

我已将此添加到我的 Angular 实用程序库中。 如果你不想写任何东西,你可以安装这个库。


结论

你怎么看? 爱它? 讨厌它? 有更好的解决方案吗? 让我知道你的想法。 祝你有美好的一天,我很快就会见到你!

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章