Rx.Subject丢失事件 [英] Rx.Subject loses events
问题描述
有人可以解释这三种变体之间的差异吗?
Can anybody explain what the differents between these 3 variants?
http://jsfiddle.net/8vx2g3fr/2/
- 首先作为感谢,所有事件都是处理。
- 但第二次输掉上一次比赛(3)
- 第三次输掉第二项赛事(2)
您能帮助我了解问题所在以及如何使第三个变体处理所有事件吗?
Could you please help me to understand what the issue is and how to make the third variant process all events?
let bs = new Rx.Subject();
bs
.subscribe(v=>{
console.log("in", v);
if (v % 2 == 0) {
setTimeout(()=>{
console.log(" out", v, "->" , v + 1);
bs.next(v+1);
}, 0);
}
});
bs.next(0);
bs.next(2);
输出:
in 0
in 2
out 0 -> 1
in 1
out 2 -> 3
in 3
2
2
let bs2 = new Rx.Subject();
bs2
.subscribe(v=>{
console.log("in", v);
if (v % 2 == 0) {
Rx.Observable.interval(0).take(1)
.map(()=>{console.log(" out", v, "->" , v + 1);return v+1;})
.subscribe(bs2);
}
});
bs2.next(0);
bs2.next(2);
输出:
in 0
in 2
out 0 -> 1
in 1
out 2 -> 3
3
3
let bs3 = new Rx.Subject();
bs3
.switchMap(v=>{
console.log("in", v);
if (v % 2 == 0) {
return Rx.Observable.interval(0).take(1)
.map(()=>{console.log(" out", v, "->" , v + 1);return v+1;});
}
return Rx.Observable.empty();
}).subscribe(bs3);
bs3.next(0);
bs3.next(2);
输出:
in 0
in 2
out 2 -> 3
in 3
推荐答案
这一切都在事实上预期的行为。
This all is in fact expected behavior.
令人困惑的是当您重复使用 Subject
和运营商如<$ c时会发生什么$ c> take()多次。
The confusing thing is what happens when you reuse Subject
and an operator such as take()
multiple times.
运营商 take(1)
需要只需一个值并发送完成
通知。由于 .subscribe(bs2)
,主题
会收到此通知。现在是最重要的部分。
当主题
收到完成
或错误
通知它标记为已停止。这意味着永远不会汇出任何项目或通知,这是Rx中的正确和预期行为。通知完成
或错误
必须是最后一次排放。
Operator take(1)
takes just a single value and send complete
notification. This notification is received by the Subject
because of .subscribe(bs2)
. Now comes the most important part.
When a Subject
receives a complete
or error
notification it marks itself as stopped. This means it will never remit any items or notifications which is correct and expected behavior in Rx. Notifications complete
or error
have to be the last emissions.
所以主题
由第一个 take(1)
完成,由值 0
( bs2.next(0)
致电)。
So the Subject
is completed by the first take(1)
which is triggered by value 0
(the bs2.next(0)
call).
然后当值 2
触发 Observable.interval(0).take(1)
的第二次运行主题
但它会被自动忽略,因为主题
已标记为已停止。
Then when value 2
triggers the second run of the Observable.interval(0).take(1)
it's received by the Subject
but it's automatically ignored because the Subject
is already marked as stopped.
第三个演示中的过程完全相同。
The process in you third demo is exactly the same.
您可以在 Subject.ts的源代码中看到它
:
h ttps://github.com/ReactiveX/rxjs/blob/master/src/Subject.ts#L56
这篇关于Rx.Subject丢失事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!