Angular Subscribers-组件损坏时自动取消订阅订阅服务器



我有一个在Angular 7上构建的大型应用程序。如果开发人员忘记在ngOnDestroy中取消订阅,我想实现一些将取消订阅RxJs订阅用户的功能。这是为了确保应用程序中没有内存泄漏。

有警卫可能吗?当路由更改时,Guard将检查上次加载的组件,并取消订阅其订阅者?

我能想到的最简单的方法是在应用程序上使用AsyncPipe

当组件被破坏时,这种方式angular将取消订阅可观察到的

参考编号:https://angular.io/api/common/AsyncPipe

是否可以使用Guards?当路由更改时,Guard将检查上次加载的组件,并取消订阅其订阅者?

很遗憾没有开箱即用。原因是很难辨别你应该取消订阅的订阅列表。例如,它可以是以下任何一种:

subscriptions : Subscription[]
subscriptions : any[]
subscriptions : any

甚至是要取消订阅的服务内的订阅。

但是,也有一些库会为您做一些这方面的工作(例如:https://tutorialsforangular.com/2020/12/14/auto-unsubscribing-from-observables-on-ngdestroy/)。不幸的是,它们仍然需要组件上的一个属性,和/或使用一些约定,即订阅数组的名称始终相同。

它也可能(因为它是开源的(,深入研究代码,并能够将其应用于routeguard等

  1. 创建包含导出类的新文件自动取消订阅

@Injectable()
export class autoUnsubscribe {
subscriptions_: any[] = []
get subscriptions(): Subscription[] {
return this.subscriptions_
}
set subscriptions(v: any) {
this.subscriptions_.push(v)
}
ngOnDestroy(): void {
this.subscriptions.forEach((s) => {
s.unsubscribe()
})
}
}

  1. 在每个组件声明上添加extends语句

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent extends autoUnsubscribe {
title = 'app';
}

  1. 在组件类中的任何位置,您都可以执行Subscribe,如下所示:

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent extends autoUnsubscribe implements OnInit{
title = 'app';


ngOnInit() {
this.subscriptions=interval(2000).subscribe(console.log)
}
}

  1. 扩展课程将负责其余的课程

建议将takeUntil运算符与ngOnDestroy一起使用。例如:

import { Component, OnDestroy, OnInit } from '@angular/core';
// RxJs 6.x+ import paths
import { filter, startWith, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { BookService } from '../books.service';

@Component({
selector: 'app-books',
templateUrl: './books.component.html'
})
export class BooksComponent implements OnDestroy, OnInit {
private ngUnsubscribe = new Subject<void>();

constructor(private booksService: BookService) { }

ngOnInit() {
this.booksService.getBooks()
.pipe(
startWith([]),
filter(books => books.length > 0),
takeUntil(this.ngUnsubscribe)
)
.subscribe(books => console.log(books));

this.booksService.getArchivedBooks()
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(archivedBooks => console.log(archivedBooks));
}

ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
}

有关更多详细信息,请参阅以下答案:Angular/RxJS我应该何时取消订阅`Subscription`

您可能还对这些tslint规则感兴趣。他们将确保RxJS在一定程度上得到正确使用。

最新更新