rxjs Observable: обработать отписаться от всех подписаться

1

У меня есть метод, который возвращает Observable

subFoo(id): Observable<number> {
    return new Observable<number>(observer => {
        setTimeout(() => {
            observer.next(id);
        }, 1000);
    });
}

теперь я подписал его три раза, а после 5 секунд отменил все:

const sub1 = subFoo(1).subscribe(result => console.log(result));
const sub2 = subFoo(2).subscribe(result => console.log(result));
const sub3 = subFoo(3).subscribe(result => console.log(result));

setTimeout(() => {
  sub1.unsubscribe();
  sub2.unsubscribe();
  sub3.unsubscribe();
}, 5000);

я могу справиться с полным unsubscrite всех слушателей?

например. (в псевдокоде):

subFoo(id): Observable<number> {
    return new Observable<number>(observer => {

        // something like this
        observer.onAllListenerAreUnsubscribed(() => {
           console.log('All Listener Are Unsubscribed!');
        });

        setTimeout(() => {
            observer.next(id);
        }, 1000);
    });
}

Демо-версия: https://stackblitz.com/edit/angular-ayl12r

Теги:
rxjs

3 ответа

1
Лучший ответ

Наблюдатель может знать о подписках на свои цепочки. Если вы хотите узнать, сколько раз кто-то подписался, вы можете считать это самостоятельно:

let subscriptions = 0;

subFoo(id): Observable<number> {
  return new Observable<number>(observer => {
    subscriptions++;
    ...
    return (() => {
      if (--subscriptions === 0) {
        // do whatever...
      }
      ...
    })
  })
})

Вы также можете собирать все подписки на стороне наблюдателя в одну подписку, а затем добавлять пользовательский обработчик при отмене подписки:

const subs = new Subscription();
subs.add(subFoo(1).subscribe(...));
subs.add(subFoo(2).subscribe(...));
subs.add(subFoo(3).subscribe(...));
subs.add(() => {
  // do whatever...
});

subs.unsubscribe(); // Will unsubscribe all subscriptions and then call your custom method.
1

Завершив сразу все ваши наблюдаемые данные, вы уверены, что не получите утечки данных. Вы можете создать объект, который будет излучать, когда наблюдаемые должны прекратить излучать и использовать оператор takeUntil() на ваших наблюдаемых, например:

const completeSubscription: Subject<void> = new Subject();

const sub1 = subFoo(1)
  .pipe(takeUntil(completeSubscription))
  .subscribe(result => console.log(result));
const sub2 = subFoo(2)
  .pipe(takeUntil(completeSubscription))
  .subscribe(result => console.log(result));
const sub3 = subFoo(3)
  .pipe(takeUntil(completeSubscription))
  .subscribe(result => console.log(result));

setTimeout(() => {
  completeSubscription.next();
  completeSubscription.complete();
}, 5000);
0

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню