javascript - 如何在 RxJS 中取消 switchmap 链?

标签 javascript rxjs switchmap

以下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 永远不会被调用。

一个真正 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>

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

相关文章:

java - 不存在类型变量 Y 的实例,因此 Calendar 符合 LiveData<Y>

javascript - 如何在 Javascript 和 JSF 中使用数据库?

javascript - 在通过 AJAX 将数据发送到资源之前验证表单。 Liferay 7.3.5

javascript - 跨子域设置 Cookies javascript 陷阱

reactjs - 为什么按钮点击触发与setTimeout()触发不同?

javascript - 如何使用 Cycle.js 和 RxJS 聚焦输入?

javascript - 使用 switchMap 取消订阅先前的 http 请求并仅获取最新的请求

javascript - 使用行类别动态排序 HTML 表

javascript - 为什么 'toPromise()' 对我不起作用

angular - 为什么我的 http 请求取消/停止 observables 流?