Есть ли какие-либо другие методы при использовании отмены подписки на подписку в Angular/RxJS?

Всякий раз, когда я сохраняю экземпляры подписки, я использую unsubscribe() во время жизненного цикла ngOnDestroy во всех компонентах. Но я хочу реализовать это в одном файле, чтобы мне не приходилось использовать unsubscribe() в каждом компоненте.

используйте takeUntilDestroyed

Naren Murali 21.05.2024 15:26

Вы можете создать класс BaseComponent, который имеет переменную для подписок: Subscription[]; и функция, которая отменяет подписку. Вы можете расширить все свои компоненты с помощью BaseComponent и использовать переменную подписки для хранения ваших потоков, а затем в своем компоненте ngDestroy вы вызываете функцию отмены подписки BaseComponent.

Gergő Kajtár 21.05.2024 16:23

Пожалуйста, опишите ваш конкретный вариант использования и покажите пример кода.

BizzyBob 21.05.2024 21:37
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
3
89
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Если вы используете 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). .

Другие вопросы по теме

Почему он сообщает мне, что свойство value цели не существует, если все элементы HTML имеют значение?
Как вызвать тот же API, когда пользователь нажимает «Повторить» в Angular 11+?
Порядок действий при подписке
Я застрял с BehaviorSubject в angular
Ошибка TS2769: никакая перегрузка не соответствует этому вызову с использованием scan() из RXJS Angular 17
Почему Rxjs switchMap выводит только последнее значение из наблюдаемого источника of()?
Я хотел бы, чтобы один Http-вызов был завершен до следующего в angular
Как выполнять несколько вызовов API параллельно и обрабатывать ответы по мере их поступления в службу HTTP в Angular?
Почему моя подписка на слияние RxJS срабатывает, когда ни один наблюдаемый объект не передает значений?
Я использую последний метод AuthGuard, он должен перенаправляться с помощью router.createUrlTree, если пользователь не вошел в систему, но он не может этого сделать