以下使用switchMap
...
Rx.Observable.timer(0, 1000)
// First switchMap
.switchMap(i => {
if (i % 2 === 0) {
console.log(i, 'is even, continue');
return Rx.Observable.of(i);
}
console.log(i, 'is odd, cancel');
return Rx.Observable.empty();
})
// Second switchMap
.switchMap(i => Rx.Observable.timer(0, 500).mapTo(i))
.subscribe(i => console.log(i));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>
...产生以下输出:
0 is even, continue
0
0
1 is odd, cancel
0 // <-------------------- why?
0 // <-------------------- why?
2 is even, continue
2
2
3 is odd, cancel
2 // <-------------------- why?
2 // <-------------------- why?
4 is even, continue
.
.
.
我希望得到以下结果:
0 is even, continue
0
0
1 is odd, cancel
2 is even, continue
2
2
3 is odd, cancel
4 is even, continue
.
.
.
我预计第一个switchMap
会在每次返回时取消所有下游,我猜这是不正确的。
有没有办法达到预期的行为?
答案 0 :(得分:1)
原因是返回一个空的observable不会导致它切换到新的observable,也就是第二个switchMap永远不会被调用。
非常hacky 解决方案是返回一个你以后可以忽略的魔法值
const CANCEL = {};
Rx.Observable.timer(0, 1000)
// First switchMap
.switchMap(i => {
if (i % 2 === 0) {
console.log(i, 'is even, continue');
return Rx.Observable.of(i);
}
console.log(i, 'is odd, send CANCEL observable');
return Rx.Observable.of(CANCEL);
})
// Second switchMap
.switchMap(i => Rx.Observable.timer(0, 500).mapTo(i))
// Filter out cancelled events
.filter(i => i != CANCEL)
.subscribe(i => console.log(i));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>