RxJS:如何引发错误然后捕捉呢?

时间:2018-11-09 12:00:50

标签: angular typescript rxjs rxjs-pipeable-operators

这与我遇到的错误无关,而是与语法问题有关。

工作流程很简单:

  • 发出一个返回布尔值的HTTP请求
  • 如果布尔值为true,则继续
  • 如果布尔值为false,则记录警告并停止流。

要解决这个问题,我当前的代码是这样:

样板

private _getBoolean() { return this.http.get(...); }
private _getData() { return this.http.get(...); }

当前代码

public getData() {
  return this._getBoolean().pipe(
    filter(bool => {
      if(!bool) {
        console.warn('Wrong server answer, stream stopped');
        return false;
      }
      return true;
    }),
    switchMap(bool => this._getData())
  );
}

我不知道为什么,但是对我来说感觉并不自然和优化。

我认为可能会简化语法,例如

public getData() {
  return this._getBoolean().pipe(
    throwError(bool => bool ? new Error('Wrong server answer, stream stopped') : null),
    catchError(err => console.warn(err)),
    switchMap(bool => this._getData())
  );
}

有没有类似的东西,或者我有正确的语法吗?

3 个答案:

答案 0 :(得分:1)

考虑下面的可观察到的值1到4。假设值3时抛出错误。该错误可以在catchError运算符中捕获,也可以在{{1内捕获}}。我相信这取决于特定的用例,是让错误一直泡到订阅者身上还是应该在订阅者上游的某个地方处理它。

subscribe

请注意,在此示例中,即使正在处理错误,可观察的操作也会完成,并且永远不会发出值4。如果您希望在遇到错误时保持可观察的状态,请查看this StackOverflow answer

答案 1 :(得分:0)

我不确定我是否能正确解决您的问题,但是您可以替换

    console.warn('Wrong server answer, stream stopped');
    return false;

使用

   Observable.throw('Some error cause')

然后用流中最接近的catch块捕获它,这基本上使您可以更改为: -如果重新抛出错误,请停止播放流 -如果返回可观察的输入,请重新启动 -返回全新的可观察结果

public getData() {
  return this._getBoolean().pipe(
    filter(bool => {
      if(!bool) {
        console.warn('Wrong server answer, stream stopped');
        //return false;
        Observable.throw('I got false where I expected true')
      }
      return true;
    }),
    switchMap(bool => this._getData())
  );
}

然后:

getData()
.any()
.operator()
.you()
.wish()
.catch(e => {
  /* Here stream will be terminated on thrown error */
})

答案 2 :(得分:0)

代替:

public getData() {
  return this._getBoolean().pipe(
    throwError(bool => bool ? new Error('Wrong server answer, stream stopped') : null),
    catchError(err => console.warn(err)),
    switchMap(bool => this._getData())
  );
}

为什么不这样:

public getData() {
  return this._getBoolean().pipe(
    tap(result => !result && throwError('Wrong server answer, stream stopped')),
    switchMap(bool => this._getData()),
    catchError(err => console.warn(err))
  );
}