我想知道behaviorSubject.value
. 根据这个答案,我们应该只通过订阅获得价值。
一个对我来说似乎没问题的情况是我使用.value
来确定下一个值来推送流,就像我切换一个简单的布尔值一样:
myBoolSubject = new BehaviorSubject(false);
toggle() {
this.myBoolSubject.next(!this.myBoolSubject.value);
}
Run Code Online (Sandbox Code Playgroud)
使用的替代方法subscribe()
如下:
toggle() {
this.myBoolSubject.pipe(take(1)).subscribe(
val => this.myBoolSubject.next(!val)
);
}
Run Code Online (Sandbox Code Playgroud)
通过查看rxjs 源代码和上述答案,这两种方法之间的区别在于.value
:
在这个简单的例子中,我不会完成这个主题,我不认为错误是一个问题,因为我只是通过这个主题推送简单的布尔值。
这是一个有效的用例behaviorSubject.value
吗?还有其他人吗?
另一种似乎可以使用的情况.value
是从先前发出的值构造一个新对象时:
private state = new BehaviorSubject<State>(INITIAL_STATE);
public state$ = this.state.asObservable();
public updateState(changes: Partial<State>){
const newState = {...this.state.value, ...changes};
this.state.next(newState);
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是将最新的状态发射缓存在另一个变量中,如下所示:
private _state = INITIAL_STATE;
private state = new BehaviorSubject<State>(INITIAL_STATE);
public state$ = this.state.asObservable();
public updateState(changes: Partial<State>){
const newState = {...this._state, ...changes};
this.state.next(this._state = newState);
}
Run Code Online (Sandbox Code Playgroud)
有没有我忽略的问题?
subscribe
和使用的布尔示例.value
const { Subject } = rxjs;
const { scan, startWith } = rxjs.operators;
myToggle$$ = new Subject();
myBool$ = myToggle$$.pipe(
scan((acc) => !acc, false),
startWith(false)
)
myBool$.subscribe(v => console.log('result: ', v));
myToggle$$.next();
myToggle$$.next();
myToggle$$.next();
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>
Run Code Online (Sandbox Code Playgroud)
避免复杂的有状态程序,在可观察流上使用干净的输入/输出函数。
您已经在使用 rxjs,您也可以说,您想使用直接命令式代码:
myBool = false;
function myToggle() { myBool = !myBool }
console.log('result: ', myBool);
myToggle();
console.log('result: ', myBool);
myToggle();
console.log('result: ', myBool);
myToggle();
console.log('result: ', myBool);
Run Code Online (Sandbox Code Playgroud)
这.value
对您的代码做了一件与干净的反应式解决方案不同的重要事情。业务逻辑被移到流之外的切换函数中。正如官方文档提到的 rxjs 的目标是拥有干净的输入/输出。这意味着input
您提供的每个流都收到相同的output
. 这意味着您的转换应该在流内部处理,没有任何副作用。
反应式编程为您处理了几个问题,或者至少使它更容易。在你展示的例子中,我看不出你为什么需要使用反应式编程。如果您完全避免rxjs
和编程,那也toggle()
完全没问题imperative
。但是当BehaviorSubject
你决定使用响应式编程的那一刻。
您can
通过使用.value
but you来实现您的问题should not
。
HTN*_*HTN -1
我不知道你的用例,但通常,你不应该toggle()
在没有参数的情况下使用,而是设置值:
setValue(v: boolean) {
this.myBoolSubject.next(v);
}
Run Code Online (Sandbox Code Playgroud)
调用者应该始终知道要设置什么值。在您确实不想给出该值的特殊情况下,使用.value
就可以了。
归档时间: |
|
查看次数: |
1115 次 |
最近记录: |