【问题标题】:RxJS - Catch and carry onRxJS - 抓住并继续
【发布时间】:2015-05-22 09:38:42
【问题描述】:

我正在努力以预期的方式处理 Rx 错误。

当我有一个 Observable(例如,来自点击流)并且发生异常时,我想捕捉它但继续。我尝试过的所有解决方案都会捕获错误,然后结束 Observable。有没有办法抓住并继续?

例如,下面的 Observable 会发出“1”,然后是“Error”,但绝不会发出“3”。

var range = Rx.Observable.range(1,3)
    .map(function(i){
      if(i === 2){
        throw "Error";
      } else {
        return i;
      }
    })
    .catch(function(e){
      return Rx.Observable.return(e)
    });

range.subscribe(function(i){
  console.log(i)
});

【问题讨论】:

  • 继续源序列的唯一方法是不抛出。你能告诉我们你的真实用例是什么吗?
  • 可观察的契约是它必须向观察者发出模式:(OnNext)* (OnCompleted | OnError)。所以当一个序列发出 OnError 时它就结束了。
  • @OliverWeichhold 真实情况是一个可观察的点击事件,其中flatMap() 可观察到一个http 请求。如果/当 http 请求失败时,点击 observable 不再发出。

标签: javascript system.reactive rxjs


【解决方案1】:

虽然由于 Observable 合约 (OnNext)* (OnCompleted|OnError) 而无法实现您的预​​期行为,但有一些实用的方法可以通过引入热 Observable 来正确解决此问题。

let hotRange = Rx.Observable.range(1,3).publish();

let safeRange = hotRange
  .map(function (i) {
    if (i === 2) {
      throw "Error";
    } else {
      return i;
    }
  })
  .retry();

safeRange.subscribe(i => console.log(i));
hotRange.connect();

See the JSBin。你在问题中提到的range Observable 是一个冷的 Observable。是behaves as a movie,所以如果发生错误,我们重新订阅,我们需要从“电影”的开头订阅,即1然后"Error"

您可能有一个隐含的假设,即Rx.Observable.range(1, 3) 是一个实时的 Observable,即“热”。既然不是,我在上面使用publish() 制作了hotRange。这样,它将独立于其订阅者发出其事件。如果我们希望在发生错误后能够“继续”,我们需要我们的源(“hotRange”)没有错误。这就是为什么range.map( ) 不是热门的 Observable 的原因。 retry() 将捕获 hotRange.map( ) 上的错误并将其替换为 hotRange.map( )。因为hotRange 很热,所以retry() 的每次执行都会有所不同,因为它不记得hotRange 之前发出的值。所以当2引起的错误在重试中被hotRange.map( )替换时,hotRange随后会发出3,并顺利通过map函数。

【讨论】:

  • 如果只有一个异常,这是有道理的。在 n 情况下工作 retry 可能会比 catch 更好。
  • @AndréStaltz。但是在 subscribe 方法中,错误处理程序没有发出任何内容。我们如何在错误处理程序中得到错误?
  • @xgrommx 这可以由retryWhen 运算符提供。
  • @paulpdaniels 你能提供一个简单的例子吗?
  • @AndréStaltz 我和@xgrommx 在同一条船上。我的解决方案是将.catch() 转换为Subject,这纯粹是为了错误。
猜你喜欢
  • 1970-01-01
  • 2012-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-28
  • 2018-11-30
  • 2012-11-15
相关资源
最近更新 更多