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

 create(options: any) {
    return timer(0, 1000).pipe(
      map(() => {
        return options;
      }),
      takeWhile(() => new Date() < options.finishDate)
    );
  }

Затем этот таймер я добавляю в массив this.timers Observables:

this.timers.push(this.create({finishDate: new Date()}))

Когда я объединяю наблюдателей:

this.mergeObserver = Observable.merge(this.timers).subscribe(x => {
   console.log(x);
});

Я вижу, что console.log(x); продолжает работу, несмотря на то, что таймер закончился.

Почему? А как остановить все таймеры в массиве?

Я могу отказаться от подписки здесь:

 Observable.merge(this.timers).subscribe(x => {
   x.unsubscribe();
});

Но это не останавливает Observable.merge.

0
user11314257 29 Окт 2019 в 01:01

1 ответ

Лучший ответ
this.mergeObserver = Observable.merge(this.timers).subscribe(x => {
   console.log(x);
});

В этом случае mergeObserver - это не наблюдаемое, а подписка. Метод subscribe возвращает подписку. Итак, переименование этого объекта в mergeSubscription и вызов функции unsubscribe для этого объекта - вот как отписаться.

Если вам нужна ссылка на наблюдаемое, вам нужно подписаться после того, как вы взяли ссылку.

this.mergeObserver = Observable.merge(this.timers);

this.mergeSubscription = this.mergeObserver.subscribe(x => {
   console.log(x);
});

А затем вы отказываетесь от подписки с помощью объекта mergeSubscription.

Observable.merge(this.timers).subscribe(x => {
   x.unsubscribe();
});

Здесь вы не можете вызвать отмену подписки на x, поскольку x - это значение, которое выходит из объединенных таймеров. Когда один из таймеров излучает, тогда слияние также выдаст это значение, это просто число и не имеет метода отказа от подписки.

1
Adrian Brand 29 Окт 2019 в 01:55
Не могли бы вы сказать мне, где я должен запускать Observable.merge(this.timers);, когда я добавляю новый элемент в массив this.timers?
 – 
user11314257
29 Окт 2019 в 02:15
И как остановить определенный таймер в массиве, когда я удаляю элемент из массива?
 – 
user11314257
29 Окт 2019 в 02:17
1
Слияние не является динамическим, Observable.merge(this.timers) создает новую наблюдаемую, и если вы хотите добавить новую наблюдаемую или удалить существующую в объединенную наблюдаемую, вы не можете сделать это динамически. Вам нужно будет управлять массивом подписок, которые передают значение субъекту, и обрабатывать добавление и удаление самостоятельно. Я не знаю оператора, который справится с этим за вас.
 – 
Adrian Brand
29 Окт 2019 в 02:22