Получить все текущие (активные) подписки

Можно ли получить все "активные" подписки, не сохраняя их вручную?

Я хочу unsubscribe от unsubscribe все "активные" подписки и не хочу ссылаться на каждую из них в массиве или переменной.

Ответы

Ответ 1

Я зависит от того, используете ли вы Subject или Observable, но, вероятно, нет способа сделать это "автоматически".

Наблюдаемые

Я не думаю, что у вас может быть такая вещь, как "Observable с подпиской", потому что вы храните Observable или Subscription:

const source = Observable.of(...)
  .map(...);

const subscription = source
  .subscribe();

Здесь source представляет собой Observable, а subscription представляет одну подписку.

Обратите внимание, что у вас может быть экземпляр Subscription котором хранятся несколько других подписок:

const subscriptions = new Subscription();

const sub1 = Observable...subscribe();
const sub2 = Observable...subscribe();
const sub3 = Observable...subscribe();

subscriptions.add(sub1).add(sub2).add(sub3);

// Then unsubscribe all of them with a single 
subscriptions.unsubscribe();

Предметы

Если вы используете темы, у них есть метод unsubscribe, см. Https://github.com/ReactiveX/rxjs/blob/master/src/Subject.ts#L96.

Однако имейте в виду, что это делает субъект "остановленным", для получения дополнительной информации см. Https://medium.com/@martin.sikora/rxjs-subjects-and-their-internal-state-7cfdee905156.

Ответ 2

Yeap. Просто вызовите свойство .observers если вы используете объект Subject из rxjs.

Надеюсь это поможет.

Ответ 3

Одним из вариантов является использование takeUntil в сочетании с Subject для остановки всех (наблюдаемых) подписок.

terminator$: Subject<boolean> = new Subject();

Observable.timer(1000)
  .do(i => console.log('timer 1: ${i}'))
  .takeUntil(terminator$)
  .subscribe();

Observable.timer(5000)
  .do(i => console.log('timer 2: ${i}'))
  .takeUntil(terminator$)
  .subscribe();

const stopSubscriptions = () => terminator$.next(true);

Ответ 4

Я думаю, что основная проблема заключается в том, что Observable (за исключением Субъекта и производных) не поддерживает ссылки на нее наблюдателей.

Без встроенных ссылок вам необходимо обращаться с ними извне в той или иной форме.

Я думаю, что лучшее, что вы могли бы достичь, - это создать переопределяемую подписку на подписку, чтобы обернуть механизм, хотя я сомневаюсь, что это того стоит.

import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';

const subscribeAndGuard = function(component, fnData, fnError = null, fnComplete = null) {

  // Define the subscription
  const sub: Subscription = this.subscribe(fnData, fnError, fnComplete);

  // Wrap component onDestroy
  if (!component.ngOnDestroy) {
    throw new Error('To use subscribeAndGuard, the component must implement ngOnDestroy');
  }
  const saved_OnDestroy = component.ngOnDestroy;
  component.ngOnDestroy = () => {
    console.log('subscribeAndGuard.onDestroy');
    sub.unsubscribe();
    // Note: need to put original back in place
    // otherwise 'this' is undefined in component.ngOnDestroy
    component.ngOnDestroy = saved_OnDestroy;
    component.ngOnDestroy();

  };

  return sub;
};

// Create an Observable extension
Observable.prototype.subscribeAndGuard = subscribeAndGuard;

// Ref: https://www.typescriptlang.org/docs/handbook/declaration-merging.html
declare module 'rxjs/Observable' {
  interface Observable<T> {
    subscribeAndGuard: typeof subscribeAndGuard;
  }
}

Задайте этот вопрос Angular/RxJs Когда я должен отказаться от Subscription

Ответ 5

Вы можете просто сохранить одну Подписку и добавить к ней.

private _subscriptions = new Subscription();   // yes you can do this!

Затем добавьте к нему

_subscriptions.add(
    this.layoutManager.width$.subscribe((w) => {

        // any nested subscriptions can also use this mechanism
        _subscriptions.add(...);
    });

Затем в ngOnDestroy() вы просто вызываете _subscriptions.unsubscribe(); ,

Я пытаюсь сделать "умный" способ сделать это, но, честно говоря, я немного переусердствовал с ним (включая ведение журнала), и это самый простой способ, с которым я столкнулся.

Ответ 6

С этим декоратором вы не должны ставить unsubscribe(), это выполняется автоматически.

Для этого вам нужно только объявить onDestroy, вам не нужно ничего вкладывать в это.

Он очень прост в использовании, я рекомендую вам его использовать.

Установка Npm

Официальная документация