如何使用retryWhen使用返回布尔值的函数?

时间:2016-10-21 19:53:55

标签: angular rxjs rxjs5 angular2-observables

这是我的代码:

this._http.post(this._url_get + extension, '', { headers: headers })
    .map(res => res['_body'])
    .retryWhen(errors => {return responseErrorProcess(errors)})

现在我需要捕获异常并将它们传递给responseErrorProcess(),如果需要重试,则返回true

我无法弄清楚如何从errors检索例外,这就是它的外观:

Subject_isScalar: falseclosed: falsehasError: falseisStopped: falseobservers: Array[0]thrownError: null__proto__: Observable`

它似乎不包含有关发生的异常的错误,而且我无法弄清楚应该返回什么以便实际重试。

2 个答案:

答案 0 :(得分:7)

retryWhen应该返回一个Observable。一旦observable发出,重试就会发生:

.retryWhen(errors => 
    //switchMap to retrieve the source error
    errors.switchMap(sourceErr => 
        //send source to processor
        responseErrorsProcess(sourceErr) ? 
        //if result is TRUE, emit (will cause retry). Else, pass on the error
        Observable.of(true): Observable.throw(sourceErr)
    )
)

如果要在处理器返回false时完成而不是出错,请将Observable.throw()替换为Observable.empty()

答案 1 :(得分:3)

可调用到retryWhen()需要返回一个Observable,它会发出completeerror来结束流或发出重新订阅的值。

例如,由于Observable.empty()

,此代码完成而不会发出错误
Observable.create(obs => {
    obs.next(1);
    obs.next(2);
    obs.error('error from source');
  })
  .retryWhen((errors) => {
      errors.subscribe(sourceError => console.log(sourceError));
      return Observable.create(obs => obs.error('inner error'));
  })
  .subscribe(
    val => console.log(val),
    err => console.log('error', err),
    _ => console.log('complete')
  );

来自源Observable的错误将errors发送到next。请参阅源代码:https://github.com/ReactiveX/rxjs/blob/master/src/operator/retryWhen.ts#L86

打印到控制台:

1
2
error inner error
error from source

查看现场演示:http://plnkr.co/edit/Fajsb54WJwB8J8hkUC6j?p=preview

根据以下评论进行编辑:

查看retryWhen()的文档:

  

错误将导致Throwable的发射导致错误发送到notificationHandler返回的Observable 。如果Observable调用 onComplete或错误,则重试将调用子订阅的完成或错误。 否则,此Observable将在特定的调度程序上重新订阅源可观察

因此从回调中返回的Observable负责决定是否重新订阅。如果它发出next(),则重新订阅。如果它发出error()complete()将其传递给子观察者。

例如你可以做(​​我没有测试这段代码):

return response.retryWhen((errors) => {
    var retrySource = new Subject();
    errors.subscribe(error => {
        if (this.responseErrorProcess(error)) retrySource.next();
        else retrySource.complete();
    });
    return retrySource;
});

根据您的内在逻辑,您可以在retrySource上触发正确的讯息。