比较来自多个 BehaviorSubjects 的最新值

Compare most recent values from multiple BehaviorSubjects

假设我有这个:

  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 在值变化时触发整数。任何时候从其中一个触发一个值,我想比较两者的两个最新值,我该怎么做?

我想要做的是return方法中的布尔值

所以我可以在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
    });
  }

虽然我们可以使用 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)');
        }
      });
    });
  }

实际上有一种更简单的方法可以使用所谓的 "projection function":

  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() 但会触发第一个新值,它不会等待新值来自所有可观察值。

您可以轻松使用.map()函数来转换您想要的数据:

isMatchedCountLessThanTotalCountMessage() {
    return Observable.combineLatest(
        this.getMatchedEventsCount(),
        this.getTotalEventsCount(),
    )
        .map(([intA, intB]) => {
            return intA > intB ? '(results ARE filtered)' : '(results are not filtered)'
        })
}