Всякий раз, когда я сохраняю экземпляры подписки, я использую unsubscribe() во время жизненного цикла ngOnDestroy во всех компонентах. Но я хочу реализовать это в одном файле, чтобы мне не приходилось использовать unsubscribe() в каждом компоненте.
Вы можете создать класс BaseComponent, который имеет переменную для подписок: Subscription[]; и функция, которая отменяет подписку. Вы можете расширить все свои компоненты с помощью BaseComponent и использовать переменную подписки для хранения ваших потоков, а затем в своем компоненте ngDestroy вы вызываете функцию отмены подписки BaseComponent.
Пожалуйста, опишите ваш конкретный вариант использования и покажите пример кода.





Если вы используете Angular 17+, используйте takeUntilDestroyed
В противном случае вы можете использовать takeUntilDestroyed в качестве библиотеки
Кроме того, каналы async автоматически отписываются при уничтожении компонента. ИМХО, у вас должно быть очень мало подписок на ваши компоненты, это должны быть крайние случаи.
Наконец, вы можете ограничить выброс наблюдаемых, используя такие операторы, как first, take, takeUntil и тому подобные. Очень маловероятно, что у вас есть тонны наблюдаемых, которые излучают непрерывно, и вам нужно подписаться на все из них. Рассмотрите возможность переделки своих рабочих процессов/кода, чтобы сделать его более эффективным.
Как уже было сказано, takeUntilDestroyed — наиболее идиоматический путь вперед.
Однако в моей компании мы используем базовый класс для всех компонентов и служб, которые должны обрабатывать отмену подписки при уничтожении. Я все еще считаю, что это проще, с меньшим количеством магии.
import { Injectable, OnDestroy } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs';
@Injectable()
export class AutoUnsubscribe implements OnDestroy {
readonly autoUnsubscriber: Observable<void> = new ReplaySubject<void>(1);
ngOnDestroy() {
if ((this.autoUnsubscriber as ReplaySubject<void>).closed) return;
(this.autoUnsubscriber as ReplaySubject<void>).next();
(this.autoUnsubscriber as ReplaySubject<void>).complete();
}
}
Затем вы можете наследовать свои компоненты, директивы или сервисы от AutoUnsubscribe и везде использовать оператор takeUntil RxJS:
@Component({...})
export class MyComponent extends AutoUnsubscribe {
constructor(someService: MyService) {
super();
someService.getSome$().pipe(
takeUntil(this.autoUnsubscriber)
).subscribe(data => {
// ...
});
}
}
Это просто становится второй натурой, и вам не нужно определять метод ngOnDestroy, который AFAICT вам следует использовать takeUntilDestroyed.
Каждому разработчику нужно просто научиться проверять, что takeUntil всегда является последним оператором в канале, непосредственно перед subscribe.
Этот шаблон также лишает большинство преимуществ использования канала async, который очень часто рассматривается как очень хороший и понятный способ управления подпиской, но, по моему опыту, он очень подвержен множественным проблемам с подпиской (например, множественным вызовам одного и того же API). .
используйте takeUntilDestroyed