【问题标题】:How to cancel switchmap chain in RxJS?如何取消 RxJS 中的 switchmap 链?
【发布时间】:2018-03-15 14:30:06
【问题描述】:

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

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

【问题讨论】:

  • 提示:让你的代码可以运行,这样其他人就能更容易地尝试解决你的问题
  • @JuanMendes 谢谢,不知道它适用于控制台输出!

标签: javascript rxjs switchmap


【解决方案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));
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"&gt;&lt;/script&gt;

【讨论】:

  • 这样行得通,但是对于我的用例来说有点不方便——我有一个可能有 8 个 switchMap 的序列,所以所有这些都必须检查这种情况。我想知道是否应该使用另一个运算符...
  • 我接受了它,因为最后我也认为这可能是唯一的方法。我会看看并尝试看看我使用 switchMap 解决这个问题的方法是否错误。谢谢!
  • 我知道,这不是很好,但 switch map 的重点是它会在发出新的 observable 时取消。在你的情况下,你不想发出一个新的 observable,所以它不会取消它。我认为您需要实现一个自定义运算符,它不会过滤掉空的可观察对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多