RXJS-BehaviorSubject:正确使用.value [英] RXJS - BehaviorSubject: proper use of .value
问题描述
我想知道 behaviorSubject.value
是否确实有适当的用途.根据此答案,我们仅应通过订阅获取值.
I'm wondering if there is actually a proper use for behaviorSubject.value
. According to to this answer, we should ONLY get values via subscribing.
在我看来还可以的情况是,我使用 .value
来确定下一个要推入流的值,例如当我切换一个简单的布尔值时:
A case where it seems okay to me is where I'm using the .value
in order to determine the next value to push through the stream, like when I'm toggling a simple boolean:
myBoolSubject = new BehaviorSubject(false);
toggle() {
this.myBoolSubject.next(!this.myBoolSubject.value);
}
使用 subscribe()
的替代方法如下:
toggle() {
this.myBoolSubject.pipe(take(1)).subscribe(
val => this.myBoolSubject.next(!val)
);
}
通过查看 rxjs源文件和前面提到的答案,这两种方法之间的区别是 .value
将在以下情况下抛出:
From looking at the rxjs source and the aforementioned answer, the difference between these two approaches are that .value
will throw when:
- 主题已完成
- 出现错误
在这种简单情况下,我不会完成本主题,并且我不认为错误是一个问题,因为我只是通过该主题推送简单的布尔值.
In this simple case, I'm not going to complete the subject and I don't think errors are a concern since I'm just pushing simple boolean values through this subject.
这是 behaviorSubject.value
的有效用例吗?还有其他人吗?
Is this a valid use case for behaviorSubject.value
? Are there others?
使用 .value
似乎还可以的另一种情况是,根据先前发出的值构造新对象时:
Another case where it seems okay to use .value
is when constructing a new object from the previously emitted 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);
}
另一种方法是将最新的状态发射缓存在另一个变量中,如下所示:
The alternative would be to cache the latest state emission in another variable, something like this:
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);
}
我有什么顾虑吗?
推荐答案
- 不带
subscribe
和.value
用法的布尔示例
- the boolean example without
subscribe
and usage of.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();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>
- 反应性编程
在可观察的流上使用干净的输入/输出功能,避免使用复杂的有状态程序.
Avoid intricate stateful programs, using clean input/output functions over observable streams.
您已经在使用rxjs,您还可以说,您想使用直接命令式代码:
You are already using rxjs where you could also say, you want to use straight imperative code:
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);
.value
对您的代码做了一件重要的事情,这与干净的反应式解决方案有所不同.将业务逻辑移到流之外,切换到切换功能.如官方文档所述,rxjs的目标是具有干净的输入/输出.这意味着您为流提供的每个 input
总是收到相同的 output
.这意味着您的转换应在流内部处理,而没有任何副作用.
The .value
does one important thing to your code that diffs from a clean reactive solution. The business logic is moved outside the stream into the toggle function. As the official docs mention the goal of rxjs is to have clean inputs/outsputs. That means that every input
you are giving your stream receives always the same output
. That means your transformation should be handled inside the stream, without any side-effects.
- 副作用的缺点
- 更严格的测试(模拟)
- 难以理解的效果
- 难以扩展的功能(代码建立在动作之上,而不是专注于效果)
- 使用rxjs可以更轻松地解决问题
- 随时间推移的异步/线程化数据(取消,暂停,..)
- 操作员
- 轻松组成不同的流(帮助您专注于应该发生的事情,而更少地关注何时发生)
- 并发(轻松拆分和合并流)
- 我自己的观点
- 总和
响应式编程可以为您解决一些问题,或者至少使它变得更容易.在显示的示例中,我看不到为什么需要使用反应式编程.如果完全避免 rxjs
和 toggle()
完全命令性
,那也完全可以.但是,当您决定使用 BehaviorSubject
的那一刻,您决定进行反应式编程.
Reactive programming handles several problems for you, or at least makes it easier. In you shown example I cannot see why you need to use reactive programming. It would be also completely fine if you avoid rxjs
and programm toggle()
fully imperative
. But the moment you dedided going with a BehaviorSubject
you decided going reactive programming.
您可以
通过使用 .value
解决问题,但您不应该
.
You can
implement your problem by using .value
but you should not
.
这篇关于RXJS-BehaviorSubject:正确使用.value的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!