如何切换rxjs变量?



如何正确做一个切换变量?

public toggleLabels$ = new BehaviorSubject<boolean>(true);
public toggleLabels() {
this.toggleLabels$.next(!this.toggleLabels$.getValue());
}

我只是得到相反的值,然后把它推回去。这是一个好方法吗?

通过scan, RxJS有一个内置的状态管理解决方案,可以用于所有状态场景(也包括一些比切换机制更复杂的场景)。

用于封装和管理状态。在初始状态建立后,对来自源的每个值应用累加器(或"reducer函数")——通过种子值(第二个参数)或来自源的第一个值。

const { Subject } = rxjs;
const { scan, startWith } = rxjs.operators;
const toggle$$ = new Subject();
const toggle$ = toggle$$.pipe(
scan((state, curr) => !state, true),
startWith(true)
);
toggle$.subscribe(console.log)
toggle$$.next()
toggle$$.next()
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.4.0/rxjs.umd.min.js"></script>

Bryan60提到我的答案并没有像问题逻辑那样完全实现行为。有两个概念上的区别:

  • 新订阅者无法获得最后值
  • no subscriber表示可观察对象不会计算/发射它的管道对丢失的特性有一个具体的解决方案如果需要:

新用户(replay last value):shareereplay操作符允许你共享一个可观察对象,并重播最后发出的值

分享订阅源和回放指定数量的排放。

没有订户(不会排放管):connectable创建了一个可观察对象,它提供了一个connect方法。调用这个函数可以让你的可观察对象变得炙手可热并被订阅。然后,它将在没有订阅的情况下发出值。

信息:这两个功能(重放和连接)在大多数时候都是不需要的。在我的上一个项目中,我们看到了过度使用BehaviorSubjectsmulticasting的启动问题。如果一次只发生一次订阅,并且在发出值之前完成订阅,则不需要重放机制。请始终记住,只有有意识的实现功能,因为它可能会影响启动,运行时性能或给您的应用程序一个意想不到的和不一致的行为。

const { Subject, connectable } = rxjs;
const { scan, startWith, shareReplay } = rxjs.operators;
const toggle$$ = new Subject();
const toggle$ = toggle$$.pipe(
scan((state, curr) => !state, true),
startWith(true),
shareReplay(1)
);
connectable(toggle$).connect()
toggle$.subscribe(v => console.log("first subscribe: ", v))
toggle$$.next()
toggle$$.next()
toggle$.subscribe(v => console.log("second subscribe: ", v))
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.4.0/rxjs.umd.min.js"></script>

这对于这么简单的东西很好,但getValue()不是我习惯使用的东西。在更复杂的情况下,它可能会变得混乱和破裂。

你通常希望在可观察对象中保留状态修改,以确保一切都按照预期的顺序发生。

你可以这样做:

// two subjects, one for saving state, one for signaling toggles
private toggleSource = new Subject();
private toggleLabelsSource = new BehaviorSubject<boolean>(true);
// keep state observables private
toggleLabels$ = this.toggleLabelsSource.asObservable();
constructor() { 
// link observables
this.toggleSource.pipe(
scan((toggle, _) => !toggle, true)
).subscribe(this.toggleLabels$);
}
public toggleLabels() {
// call next on toggle signal.
this.toggleSource.next(null);
}

对于这么简单的事情来说,这太复杂了,但是当你处理更复杂的状态转换时,这种模式更有意义。

创建一个包含:

的服务
private toggleValue = true;
private toggleLabelsSource = new BehaviorSubject<boolean>(this.toggleValue);
currentToggleLabels = this.toggleLabelsSource.asObservable();

toggleLabels(): void {
this.toggleValue = !this.toggleValue;
this.toggleLabelsSource.next(this.toggleValue);
}

然后你可以听currentToggleLabels和切换toggleLabels()

最新更新