Rxjs 如何使可观察性在抛出错误的情况下继续发出值

Rxjs 如何使可观察性在抛出错误的情况下继续发出值,rxjs,rxjs5,Rxjs,Rxjs5,错误被抛出并替换。但执行结束了。如何使可观察发射10个元素 const Rx = require('rxjs/Rx') Rx.Observable.interval(1000) .map((i) => { if (i === 2) throw(new Error('omg')) return i }) .take(10) .catch((err) => { return Rx.Observable.of('ok, we caught an e

错误被抛出并替换。但执行结束了。如何使可观察发射10个元素

const Rx = require('rxjs/Rx')

Rx.Observable.interval(1000)
  .map((i) => {
    if (i === 2) throw(new Error('omg'))
    return i
  })
  .take(10)
  .catch((err) => {
    return Rx.Observable.of('ok, we caught an error, but we don\'t want to exit')
  })
  .do(console.log, console.error)
  .subscribe()

我不是RxJS大师,但我想尝试回答这个问题

用RxJS抛出一个错误会终止可观察的对象。因此,您无法恢复该操作,只能尝试重试/重复可观察的操作

Rx.Observable.interval(1000)
  .map((i) => {
    if (i === 2) throw(new Error('omg'))
    return i
  })
  .catch((err) => {
    return Rx.Observable.of('ok, we caught an error, but we don\'t want to exit')
  })
  .repeat()
  .take(10)
  .subscribe((x) => console.log('result', x))
如果您不想重播错误,并且必须只获取原始的10个元素,那么您可以
返回null
而不是
抛出新错误
,并且在
获取(10)
之前只
过滤(x=>x)

否则,您可以使用
retryWhen
重复可观察到的错误。请注意,这将导致2项失败,然后它将在0、1、。。。它在2次失败后结束,但仍然只需要10项

Rx.Observable.interval(1000)
  .map((i) => {
    if (i === 2) throw(new Error('omg'))
    return i
  })
  .retryWhen((errors) => errors.scan(
    (errorCount, err) => {
        if(errorCount >= 2) {
            throw err;
        }

        return errorCount + 1;
    }, 0)
  )
  .take(10)
  .catch((err) => {
    return Rx.Observable.of('ok, we caught an error, but we don\'t want to exit')
  })
  .subscribe((x) => console.log('result', x))
您还可以使用
repeat
在可观察到的内容结束时不断重复。这可能不是你想要的,但我还是想把它作为一个选项展示给你。你需要注意你的位置,它还“计算”了可观察到的排放捕获量

Rx.Observable.interval(1000)
  .map((i) => {
    if (i === 2) throw(new Error('omg'))
    return i
  })
  .catch((err) => {
    return Rx.Observable.of('ok, we caught an error, but we don\'t want to exit')
  })
  .repeat()
  .take(10)
  .subscribe((x) => console.log('result', x))

可观察合同为
OnNext*(OnError | OnCompleted)+

一旦序列结束,下游操作员必须取消订阅。您只能重新订阅管道。如果您的观察对象是冷的,那么您可以使用
重试
操作符重新订阅

observable
.retry()
.take(10)
.subscribe()

您可以提供一个函数来处理错误并返回一个可观察值。您将需要使用
flatMap
,因为您将使用高阶函数

function handleError(cb){
    return (val) => {
        try{
            return Rx.Observable.of(cb(val));
        }catch(err){
            console.error(`${err}`);
            return Rx.Observable.empty();
        }
    }
}

Rx.Observable.interval(1000)
    .flatMap(handleError(i => {
        if (i === 2) throw(new Error('omg'))
        return i;
    }))
    .take(10)
    .do(console.log)
    .subscribe()

// emits
// 0
// 1
// "Error: omg"
// 3
// 4
// 5
// 6
// 7
// 8
// 9
// 10

另一个不太适合您的示例代码但值得一提的示例,RxJS的首席开发人员Ben Lesh在一篇名为。中途有一段叫做“RxJS中的Gotchas”

[…]由于Rx观测值不会“捕获”错误,我们可能会遇到一些错误 奇怪的行为。错误“陷阱”是我自己的一种行为 嘲笑实施的承诺,但在多播场景中可能 这是正确的举动。当我说Rx可观测时,我的意思不是 “陷阱”错误基本上是指当一个错误渗透到 观察者链,如果错误未处理,将重新抛出

下面是该部分的一个代码示例(最简单但不是最有效):