在Ajax错误之后RxJS继续侦听

Jon*_*ely 20 javascript ajax error-handling reactive-extensions-js rxjs

当内部可观察错误(Ajax请求)时,RxJs停止侦听单击事件.我试图弄清楚如何将事件监听器挂钩到按钮单击事件并优雅地处理内部ajax错误.

这是我的示例代码和plunkr的链接

var input = $("#testBtn");
var test = Rx.Observable.fromEvent(input,'click');

var testAjax = function() {
  return Rx.Observable.range(0,3).then(function(x){ 
    if(x==2)throw "RAWR"; //Simulating a promise error.
    return x;
  });
}

test.map(function(){
  return Rx.Observable.when(testAjax());
})
.switchLatest()
.subscribe(
  function (x) {
      console.log('Next: ', x);
  },
  function (err) {
      console.log('Error: ' + err);   
  },
  function () {
      console.log('Completed');   
  });
Run Code Online (Sandbox Code Playgroud)

http://plnkr.co/edit/NGMB7RkBbpN1ji4mfzih

cwh*_*ris 22

您可以使用catch运算符(或catchException别名)来捕获和处理在observable中发生的错误,以便不会向订阅者通知错误.

忽略错误:

return Rx.Observable
    .when(testAjax())
    .catch(Rx.Observable.empty()); // continues with an empty obs after error.
Run Code Online (Sandbox Code Playgroud)

处理错误:

var empty = Rx.Observable.return('default value');
return Rx.Observable
    .when(testAjax())
    .catch(function (error) {
        console.log('error:', error);
        return empty;
    });
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!.我当时就像90%.我发现运行catch()是我需要在内部observable上运行但无法弄清楚返回值应该是什么.最终`Rx.Observable.Empty()`就是我所遗漏的.这是一个更新的plunker http://plnkr.co/edit/UtReTejs524rX2DKbIoj?p=preview (2认同)
  • 如果我希望订阅者收到错误通知并且流正常继续怎么办? (2认同)

pjs*_*pjs 6

我遇到了自己的问题,解释了这个(和onErrorResumeNext)如何运作.我遇到的斗争是在什么情况下捕获(或接下来的简历).对我来说有意义的简单口语翻译如下:

给定可观察的流(或可观察的),catch(或onErrorResumeNext)将消耗该错误并允许您提供一个或多个可观察量以继续原始流.

关键的一点就是你的原始资源被中断并被你在catch/ onErrorResumeNext函数中提供的observable所取代.这意味着,如果您有这样的事情:

var src = Rx.Observable
    .interval(500)
    .take(10)
    .select(function(x) {
        if (x == 5) {
            return Rx.Observable.throw('Simulated Failure');
        }

        return Rx.Observable.return(x * 2);
    })
Run Code Online (Sandbox Code Playgroud)

然后添加.catch(Rx.Observable.return('N/A'))或者.onErrorResumeNext(Rx.Observable.return('N/A'))实际上不会继续你的流(由它来源interval),而是用最终的observable(the N/A)结束流.

如果您正在寻找优雅地处理故障并继续原始流,您需要更多的东西.select(function(x) { return x.catch(Rx.Observable.return('N/A')); }).现在,您的流将替换流中因捕获的默认值而失败的任何可观察元素,然后继续使用现有源流.

var src = Rx.Observable
    .interval(500)
    .take(10)
    .select(function(x) {
        if (x == 5) {
            return Rx.Observable.throw('Simulated Failure');
        }

        return Rx.Observable.return(x * 2);
    })
    //.catch(Rx.Observable.return('N/A'))
    //.onErrorResumeNext(Rx.Observable.return('N/A'))
    .select(function(x) { return x.catch(Rx.Observable.return('N/A')); })
    .selectMany(function(x) { return x; });


var sub = src.subscribe(
    function (x) { console.log(x); },
    function (x) { console.log(x); },
    function () { console.log('DONE'); }
);

// OUTPUT:
// 0
// 2
// 4
// 6
// 8
// N/A
// 12
// 14
// 16
// 18
// DONE
Run Code Online (Sandbox Code Playgroud)

这是一个JSFiddle,它显示了这一点.