3

这是我的代码:

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`

它似乎不包含有关发生的异常的错误,而且我不知道应该返回什么才能实际重试。

4

2 回答 2

8

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()

于 2016-10-23T14:27:20.097 回答
5

可调用对象retryWhen()需要返回一个 Observable,该 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 的错误被发送到errorsas 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 或错误,则 retry 将在子订阅上调用完成或错误。否则,此 Observable 将在特定调度程序上重新订阅源 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

于 2016-10-22T15:32:04.080 回答