RxJs - 如何只捕获特定类型的异常而不中止序列

时间:2015-06-12 05:17:44

标签: rxjs

RxJs似乎没有catch()方法的变体,它只允许捕获某种类型的异常。但很多时候我发现自己处于需要这种操作员的境地。

例如,映像我需要解析日志文件的每一行并打印已解析的消息。日志文件的某些行可能已损坏,但我真的不在乎,只想为此行输出“已损坏的日志消息”并继续到下一行。

如果catch()确实允许我们指定一个特定类型的错误来捕获并传递所有其他错误,那么我们可以做一些像下面的伪代码

readLogs()
.flatMap parseLog
.catchOnly ParseError, () ->
  'Log message corrupted'
.subscribe (logMessage) ->
  console.log logMessage

我想知道在catach()的当前限制下,RxJs的正确方法是什么。

3 个答案:

答案 0 :(得分:2)

您需要嵌套catch以防止错误终止整个链,您需要将拆分解析的逻辑分开行:

function handleErrors(e) {
    return (e instanceof ParseError) ? 
            Rx.Observable.just("Log message corrupted") : Rx.Observable.throw(e);
}

readLogs()
.flatMap(splitLines)
.flatMap(function(line) {
  return Rx.Observable.just(line).map(parseLine).catch(handleErrors);
})
.subscribe(function(parsedLine) {
  console.log(parsedLine);
}, function(e) {
  console.error('Fatal error: ' + e);
});

答案 1 :(得分:0)

catch / catchOnly操作受限于它可以做什么。

Observable链中的下层链接无法告诉更高的链接忽略错误。在 flatMap parseLog 发出错误后,它就完成了, catchOnly 没有机制告诉它回溯并忽略该错误。

这意味着 catchOnly 操作最多可以在发现特定错误时重新启动序列。

为了达到您要查找并保持序列运行的效果, flatMap parseLog 应该首先避免产生错误条件。所以 parseLog 需要一个包装器来捕获 ParseError 异常并将其转换为有效的logMessage。

答案 2 :(得分:0)

        .catch(error => {
            if (whatever) {
                console.log('I handle this in a cool way')
                return Observable.empty(); // Or an observable that emits whatever you want
            } else {
                return Observable.throw(error);
            }