如何获得以前的价值主题?
How to get previous value Subject?
我有以下主题:
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);
}
怎么做?
你最好在这里使用 BehaviorSubject
。它保存当前值,也有 value
getter 来获取它。
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 结合使用。
更新:避免同步.value
getter
我可以想出 2 种方法来使用流中的先前值。
- 直接使用
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]
- 如果您不希望在开始时使用默认值,您可以将
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 以反映这些变化。
我有以下主题:
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);
}
怎么做?
你最好在这里使用 BehaviorSubject
。它保存当前值,也有 value
getter 来获取它。
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 结合使用。
更新:避免同步.value
getter
我可以想出 2 种方法来使用流中的先前值。
- 直接使用
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]
- 如果您不希望在开始时使用默认值,您可以将
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 以反映这些变化。