具有CombineLatest的BehaviorSubject的奇怪行为

时间:2018-07-04 21:39:34

标签: javascript angular rxjs rxjs6

我是Rxjs的新手,并且遇到了带有scan和CombineLatest运算符的BehaviorSubject的奇怪行为。下面是简单组件的代码:

import { Component, OnInit } from '@angular/core';
import { BehaviorSubject, of, combineLatest } from 'rxjs';
import { switchMap, scan} from 'rxjs/operators';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  stream1 = new BehaviorSubject('');
  stream2 = new BehaviorSubject(0);
  result: any;
  counter = 1;

  sub: any;

  constructor() {}

  ngOnInit() {
    this.sub = this.stream2.pipe(
      scan((acc, v) => [...acc, v], []),
    );
    this.result = this.stream1.pipe(
      switchMap(data => combineLatest(of(data), this.sub))
    ).subscribe(val => console.log(val));
    this.stream1.next('init');
    this.stream2.pipe(scan((acc, v) => [...acc, v], [])).subscribe(val => console.log('Track Stream 2: ', val));
  }

  onClick() {
    this.stream2.next(this.counter++);
  }

  onClick2() {
    this.stream1.next('test ' + this.counter);
  }
}


<button (click)="onClick()">Test</button>
<button (click)="onClick2()">Test2</button>

作为“ this.result”流的结果,我希望数组中的第一个值(即“ this.stream1”中的最新值和第二个值)是一个数组,其中包含所有由“ this.sub”收集的值,但是实际上,我从“ this.sub”中仅获得了最新值,好像我的扫描运算符被忽略了。 参见附件img:

enter image description here

能请您解释一下如何达到期望的结果吗? 谢谢大家!

Ps。 Angular v6.0.7和RxJs v6.2.1

1 个答案:

答案 0 :(得分:0)

好像我找到了解决方案。我可以使用shareReplay(0)运算符来修复它,但是我不确定这是否是最好的解决方案,如果可以的话,请予以纠正:)

  ngOnInit() {
    this.sup = this.stream2.pipe(
      scan((acc, v) => [...acc, v], []),
      shareReplay(0) // Solution
    );
    this.result = this.stream1.pipe(
      switchMap(ud => combineLatest(of(ud), this.sup))
      // withLatestFrom(this.sup)
    ).subscribe(val => console.log(val));
    this.stream1.next('second');
    this.stream2.pipe(scan((acc, v) => [...acc, v], [])).subscribe(val => console.log('Stream 2: ', val));
  }