RxJS -抓住并坚持下去



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

当我有一个可观察对象(例如,从点击流)和一个异常发生,我想抓住它,但继续。我尝试过的所有解决方案都捕获了错误,然后结束了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),你的预期行为无法实现,但通过引入热可观察对象,有一些实际的方法可以正确解决这个问题。

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();

查看JSBin。你在问题中提到的range Observable是一个冷Observable。它的行为就像一部电影,所以如果发生错误而我们重新订阅,我们需要从"电影"的开头订阅,即1然后"Error"

你可能有一个隐含的假设,即Rx.Observable.range(1, 3)是一个活动的Observable,即"hot"。因为它不是,我让hotRange上面使用publish()。这样,它将独立于其订阅者发出其事件。如果我们希望能够在发生错误后"继续",我们需要源("hotRange")没有错误。这就是为什么range.map( )不是热门的Observable。retry()将捕获hotRange.map( )上的错误并将其替换为hotRange.map( )。因为hotRange是热的,所以retry()的每次执行都会有所不同,因为它不会记住hotRange之前发出的值。所以在重试中,当2引起的错误被hotRange.map( )所取代时,hotRange随后会发出3,并且没有错误地传递map函数。

相关内容

  • 没有找到相关文章

最新更新