使用Angular2异步管道处理错误

时间:2016-07-06 17:30:04

标签: error-handling angular rxjs

我正在使用Angular2异步管道将值流式传输到DOM中。这是一个非常简单的例子:

const stream = Observable.interval(1000)
  .take(5)
  .map(n => { if (n === 3) throw "ERROR"; return n; });

<div *ngFor="for num of stream | async">
  {{num}}
</div>

<div id="error"></div>

我想要做的是显示1-5的序列,但是在错误项目(3)上,以某种方式填充#error div并显示错误消息。

这似乎需要两件事:首先是Angular异步管道能够做出智能错误的能力,我没有看到任何迹象。看一下源代码,显然它会抛出一个JS异常,这似乎不太友好。

其次是错误后重启或继续序列的能力。我已阅读有关catchonErrorResumeNext等内容,但它们都涉及另一个序列,该序列将在出错时切换为。这使得生成流的逻辑变得非常复杂,我想在其上放置一系列数字(在这个简单的例子中)。我有一种下沉的感觉,一旦发生错误,游戏结束并且可观察完成,并且只能用不同的可观察量“重新启动”。我还在学习可观察的东西;事实上是这样吗?

所以我的问题有两个:

  1. Angular2的异步管道可以做一些智能的错误吗?
  2. 在观察到错误后,observables有一些简单的方法可以继续吗?

3 个答案:

答案 0 :(得分:10)

是的,关于捕获操作员以及发生错误后能够做某事的能力是对的......

我会利用catch运算符来捕获错误并执行某些操作:

const stream = Observable.interval(1000)
  .take(5)
  .map(n => {
    if (n === 3) {
      throw Observable.throw(n);
    }
    return n;
  })
  .catch(err => {
    this.error = error;
    (...)
  });

并在模板中:

<div>{{error}}</div>

为了能够继续初始的observable,你需要从发生错误的那一点开始创建一个新的observable:

createObservable(i) {
  return Observable.interval(1000)
    .range(i + 1, 5 - i)
    .take(5 - i)
  });
}

并在catch回调中使用它:

  .catch(err => {
    this.error = error;
    return this.createObservable(err);
  });

这两个问题可以帮到你:

答案 1 :(得分:8)

1)否,async管道订阅并取消订阅并返回它收到的事件。您需要在收到async管道之前处理错误。

2)你可以使用catch运算符,当它返回一个observable时,它的值由.catch(err => Observable.of(-1))而不是错误发出。

您可以使用它来发出一个特殊的错误&#34;值,然后使用类似*ngIf="num === -1的内容以某种特殊方式显示错误值。

您可以找到有关此https://blog.thoughtram.io/angular/2017/02/27/three-things-you-didnt-know-about-the-async-pipe.html

的更多信息

答案 2 :(得分:0)

@Thierry Templier 的回答是正确的,但现在有点过时了。以下是如何使用最新的 RXJS。

this.myObservable$ = this.myService.myFunc().pipe(
  catchError(() => of([])) // this will emit [] if the request fails - u could handle this [] emit on error in the service itself
)

然后 HTML 正常:

<div *ngFor="let xxx of (myObservable$ | async)">
</div>

注意在 Observable 名称末尾的 $ 是 Angular 推荐的表示 Observable 的方式。