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每次返回时都会取消所有下游内容,我认为这是不正确的。

有没有办法实现预期的行为?

最佳答案

原因是返回一个空的observable不会导致它切换到新的observable,也就是第二个switchMap永远不会被调用。

一个真正的解决方案是返回一个魔术值,您以后可以忽略它



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>

关于javascript - 如何取消RxJS中的switchmap链?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49302119/

10-12 07:38