RxJS - 抓住并继续

Max*_*lmo 6 javascript system.reactive rxjs

我正在努力以我期望的方式处理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)
});
Run Code Online (Sandbox Code Playgroud)

And*_*ltz 9

虽然由于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();
Run Code Online (Sandbox Code Playgroud)

参见JSBin.range你在问题中提到的Observable是一个冷的Observable.它表现为一部电影,所以如果有错误发生,我们重新订阅,我们需要从"电影"的开始认购,也就是说,1然后"Error".

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