Сравните самые последние значения из нескольких BehaviorSubject

Скажем, у меня есть это:

  isMatchedCountLessThanTotalCountMessage(){
       // I want to implement this
       // "returns" a string asynchronously
  }

  getMatchedEventsCount() {
    return this.dcs.matchCount.asObservable();
  }

  getTotalEventsCount() {
    return this.dcs.totalCount.asObservable();
  }

matchedCount и totalCount выглядят так:

  public matchCount = new BehaviorSubject<number>(0);
  public totalCount = new BehaviorSubject<number>(0);

эти Observables запускают целые числа при изменении значений. Каждый раз, когда значение запускается из любого из них, я хочу сравнить два самых последних значения из обоих, как мне это сделать?

Я хочу вернуть логическое значение из метода

поэтому я могу отобразить в HTML:

 <div>{{(isMatchedCountLessThanTotalCountMessage() | async)}}</div>

Я думаю, что Observable.zip может помочь:

isMatchedCountLessThanTotalCountMessage(){
    return Observable.zip(
      this.getMatchedEventsCount(),
      this.getTotalEventsCount()
    )
    .subscribe(function(v){
      const intA = v[0];
      const intB = v[1];

        if(intA > intB)
         // but I don't know how to send a message the HTML from here
    });
  }

person Alexander Mills    schedule 06.02.2018    source источник


Ответы (2)


Вы можете легко использовать функцию .map() для преобразования нужных данных:

isMatchedCountLessThanTotalCountMessage() {
    return Observable.combineLatest(
        this.getMatchedEventsCount(),
        this.getTotalEventsCount(),
    )
        .map(([intA, intB]) => {
            return intA > intB ? '(results ARE filtered)' : '(results are not filtered)'
        })
}
person CozyAzure    schedule 06.02.2018
comment
@AlexanderMills, вы действительно должны принимать ответ только после того, как он сработает / решит ваши проблемы - person CozyAzure; 06.02.2018

Это работает, хотя мы могли бы использовать что-то другое, кроме Observable.zip.

 isMatchedCountLessThanTotalCount() {
    return Observable.create(obs => {
      return Observable.zip(
        this.getMatchedEventsCount(),
        this.getTotalEventsCount()
      )
      .subscribe(v => {
        if ((v[1] - v[0]) > 0) {
          obs.next('(results ARE filtered)')
        }
        else {
          obs.next('(results are not filtered)');
        }
      });
    });
  }

и на самом деле есть более простой способ сделать это, используя так называемую «функцию проекции»:

  isMatchedCountLessThanTotalCount() {
    return Observable.combineLatest(
      this.getMatchedEventsCount(),
      this.getTotalEventsCount(),
      function (one, two) {
        if ((two - one) > 0) {
          return '(results ARE filtered)'
        }
        return '(results are not filtered)';
      }
    )
  }

Observable.combineLatest() похож на Observable.zip(), но срабатывает при первом новом значении, он не дожидается появления новых значений от всех наблюдаемых.

person Alexander Mills    schedule 06.02.2018