Сигнал о завершении ReplaySubject

Я пытаюсь найти хороший способ сигнализировать о том, что ReplaySubject в настоящее время «пустой».

import {ReplaySubject} from 'rxjs/ReplaySubject';
const rs = new ReplaySubject<Object>();

 // ...
constructor(){
  this.sub =  rs.subscribe(...);
}

каждый раз, когда вызывается конструктор, он будет воспроизводить все элементы из субъекта. Однако мой вопрос: есть ли какое-то событие, которое мы можем прослушать, которое сообщает нам, когда тема становится пустой?

Единственное, что я могу придумать, это запустить пользовательское/другое событие, когда тема будет завершена, что-то вроде этого:

rs.next({done:true});

Является ли передача данных методу next() лучшим способом сигнализировать о том, что ReplaySubject (временно) пуст/отсутствует в событиях?


person Community    schedule 15.02.2018    source источник
comment
Это немного сбивает с толку то, что вы ищете. Под завершением вы подразумеваете звонок complete()? Под пустым вы имеете в виду, что он еще не получил никакого next() вызова? Субъекты не могут стать пустыми, вызвав любой из их методов.   -  person martin    schedule 15.02.2018
comment
Под завершением я имел в виду, что это последний раз, когда next() звонили по этому вопросу.   -  person    schedule 15.02.2018


Ответы (2)


Поскольку субъект также является наблюдателем, вы можете вызвать complete() после последнего вызова next(). Затем вы можете прослушать его с 3-м параметром метода subscribe(...).

const rs = new ReplaySubject<Object>();
rs.next({a: 1})
rs.complete()

rs.subscribe(
    obj => console.log(obj),
    error => {},
    () => console.log('completed')
);
// Outputs
// {a: 1} completed
person Voskanyan David    schedule 22.02.2018

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

const last$ = rs.replay(1);

Затем вы просто объедините Latest и просканируете... как только вы достигнете элемента, испускаемого last$, ваш ReplaySubject завершит воспроизведение:

this.sub = Observable.combineLatest(
  rs,
  last$.take(1)
).scan((acc: { item: Object, isReplay: boolean }, curr: [Object, Object]) => {
    return {item: curr[0], isReplay: acc.isReplay && curr[0] !== curr[1]};
  }, {isReplay: true}
).subscribe(...);
person Miller    schedule 15.02.2018
comment
Мистер Миллер, как вы думаете, ответ от @Voskanyan David лучше? кажется проще - person ; 24.02.2018
comment
Формулировка вашего вопроса говорит о том, что лучший способ сигнализировать о том, что ReplaySubject (временно) пуст / вне событий. Ответ @Voskanyan David сообщает вам, когда ReplaySubject завершен (постоянно вне событий) - person Miller; 24.02.2018