Странное поведение BehaviorSubject с комбинатомПоследний - PullRequest
0 голосов
/ 05 июля 2018

Я новичок в Rxjs, и я столкнулся со странным поведением BehaviorSubject с оператором scan и ОбъединитьПоследний. Ниже код простого компонента:

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', а 2-е значение - это массив со всеми значениями, которые были собраны this.sub, но на самом деле из "this.sub" я получаю только последнее значение, как будто мой оператор сканирования был проигнорирован .. Смотрите прикрепленный img:

enter image description here

Не могли бы вы объяснить, как достичь желаемого результата? Спасибо всем!

Ps. Angular v6.0.7 и RxJs v6.2.1

1 Ответ

0 голосов
/ 05 июля 2018

Похоже, я нашел решение. Я мог бы исправить это с помощью оператора 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));
  }
...