假设我们有以下代码(Stackblitz):
public counter: number = 0; // Some arbitrary global state
public ngOnInit(): void {
const subj: Subject<number> = new Subject<number>();
const obs: Observable<number> = subj.asObservable().pipe(
tap((): void => {
++this.counter;
}));
// this.counter increments for each subscription.
// But supposed to increment once per obs new value emition.
obs.subscribe();
obs.subscribe();
obs.subscribe();
subj.next(1);
// Now this.counter === 3
}
结果是this.counter
在执行上述操作后等于3
,每次订阅都会增加一次。
但是,我们如何以反应方式每Observable
的新价值排放增加一次呢?
我知道我们应该避免在Reactive流程之外的状态,但在现实世界的应用程序中仍然需要时间。
答案 0 :(得分:2)
您看到号码3
的原因略有不同。当您使用of(1)
时,它会发出一个next
通知,然后发出complete
通知。每次拨打obs.subscribe()
时都会这样做。
因此,如果您想查看1
,您需要创建一个中间主题,您在其中进行所有订阅,然后此中间主题订阅源Observable(最简单地使用publish()
运算符创建主题你):
const obs: ConnectableObservable<number> = of(1).pipe(
tap((): void => {
++this.counter;
}),
publish(),
) as ConnectableObservable<number>;
obs.subscribe();
obs.subscribe();
obs.subscribe();
obs.connect();
您的最新演示:https://stackblitz.com/edit/rxjs-update-global-state-ejdkie?file=app/app.component.ts
请注意,of(1)
无论如何都会发出complete
通知,这意味着publish()
内的主题也会完整。这可能(或可能不是)对你来说是一个问题,但它实际上取决于你的用例。
修改:这是更新的演示,其中来源为主题:https://stackblitz.com/edit/rxjs-update-global-state-bws36m?file=app/app.component.ts
答案 1 :(得分:0)
请尝试一次这样的事情。我无法在任何地方运行它。如果它出错,请告诉我
public counter: number = 0;
public items: any = [];
public ngOnInit(): void {
const obs: Observable<number> = of(1).pipe(
tap((value): void => {
if(! Array.prototype.includes(value)) {
this.items.push(value);
++this.counter;
}
}));
// this.counter increments for each subscription.
// How to make it increment once per obs new value emission.
obs.subscribe(1);
obs.subscribe(2);
obs.subscribe(1);
// Now this.counter === 3
}