首页 > 解决方案 > 如何获得以前的价值主题?

问题描述

我有以下主题:

  private active = new Subject<P>();
  prev: Custom<any>;

  set(p: P): void {
    this.active.next(p);
  }

我想从active主题中提取数据并将其设置为prev

 set(p: P): void {
     this.prev = this.active;
     this.active.next(p);
 }

怎么做?

标签: angularrxjsbehaviorsubject

解决方案


你最好在BehaviorSubject这里使用。它保存当前值,也有value获取它的方法。

private active = new BehaviorSubject<P>(null);  // <-- default value required
prev: Custom<any>;

set(p: P): void {
  this.prev = this.active.value;
  this.active.next(p);
}

但这实际上看起来并不那么干净。您打算如何使用该prev值?也许有一种更清洁的方式使用ReplaySubject缓冲区 2。

更新:避免同步.valuegetter

我可以想出两种方法来使用流中的先前值。

  1. pairwise与运营商的直接方式。它将最后一个值和当前值作为数组发出。不利的一面是它不会发出第一个值,因为还没有当前的先前状态。可以由startWith操作员调整。
import { Subject } from "rxjs";
import { startWith, pairwise} from "rxjs/operators";

export class AppComponent {
  subSource = new Subject<any>();
  sub$ = this.subSource.pipe(
    startWith(null),
    pairwise()
  );

  constructor() {
    this.sub$.subscribe(val => console.log("pairwise:", val));

    this.subSource.next(1);
    this.subSource.next(2);
    this.subSource.next(3);
  }
}

// expected output:
// pairwise: [null, 1]
// pairwise: [1, 2]
// pairwise: [2, 3]
  1. 如果您不希望在开始时使用默认值,则可以使用ReplaySubject缓冲区 2 并使用scan运算符仅发出先前值和当前值。
import { ReplaySubject } from "rxjs";
import { scan } from "rxjs/operators";

export class AppComponent {
  replaySubSource = new ReplaySubject<any>(2);
  replaySub$ = this.replaySubSource.pipe(
    scan((acc, curr) => {
      acc.push(curr);
      return acc.slice(-2);
    }, [])
  );

  constructor() {
    this.replaySub$.subscribe(val => console.log("replay subject:", val));

    this.replaySubSource.next(1);
    this.replaySubSource.next(2);
    this.replaySubSource.next(3);
  }
}

// replay subject: [1]
// replay subject: [1, 2]
// replay subject: [2, 3]

工作示例:Stackblitz

至于关于使用默认值的问题find。不,我不认为在find那里使用它很脏。实际上,find是否可以根据谓词获取特定元素,所以我认为您的使用没有任何错误。

更新:发射为{prev: .., active: ..}.

您只需要将map操作员通过管道传输到最后并根据要求发出。

sub$ = this.subSource.pipe(
  startWith(null),
  pairwise(),
  map(([prev, active]) => ({ prev: prev, active: active }))
);

// expected output:
// pairwise: {prev: null, active: 1}
// pairwise: {prev: 1, active: 2}
// pairwise: {prev: 2, active: 3}

我还调整了Stackblitz以反映这些变化。


推荐阅读