可观察的取消执行功能

时间:2019-05-04 00:42:55

标签: javascript rxjs rxjs6

我想观察一下,当取消订阅时,它会调用一个函数,但只有在取消订阅而没有错误且没有完成时才调用该函数。我尝试构建的可观察对象通常会与另一个可观察对象竞争。我想当另一个可观察的“获胜者”执行此功能。

我尝试了finalize运算符,但它总是执行。

playback.ts

Electron

errorobs.ts

package.json

我在这里https://codesandbox.io/s/q7pwowm4l6做了一个小样

单击“开始”以启动“可观察”。

单击“取消”以使其他可观察获胜

点击错误会生成错误

2 个答案:

答案 0 :(得分:1)

实现此目标的一种方法是使用自定义运算符,例如下面的onCancel()

const {Observable} = rxjs

function onCancel(f) {
  return observable => new Observable(observer => {
    let completed = false
    let errored = false
    const subscription = observable.subscribe({
      next: v => observer.next(v),
      error: e => {
        errored = true
        observer.error(e)
      },
      complete: () => {
        completed = true
        observer.complete()
      }
    })
    return () => {
      subscription.unsubscribe()
      if (!completed && !errored) f()
    }
  })
}

// Test:
const {interval} = rxjs
const {take} = rxjs.operators

// This one gets cancelled:
const s = interval(200).pipe(
  onCancel(() => console.warn('s cancelled!'))
).subscribe(() => {})
setTimeout(() => s.unsubscribe(), 500) 

// This one completes before unsubscribe():
const q = interval(200).pipe(
  take(2),
  onCancel(() => console.warn('q cancelled!'))
).subscribe(() => {})
setTimeout(() => q.unsubscribe(), 500)
<script src="//unpkg.com/rxjs@6/bundles/rxjs.umd.min.js"></script>

答案 1 :(得分:1)

它确实如您所描述的那样起作用。 finalize在处理链时,所有订户退订,链错误或完成时执行。

RxJS Github页面上已存在此功能的问题:https://github.com/ReactiveX/rxjs/issues/2823

在上面的链接中,您可以看到一个自定义运算符的示例,该示例将原因添加到finalize运算符中。

我必须亲自处理此用例,并将此运算符添加到我自己的RxJS运算符集合中:https://github.com/martinsik/rxjs-extra/blob/master/doc/finalizeWithReason.md