问题
I am trying to get my code updated so that I am able to use refresh tokens to keep a user logged in. I intend to do this using the Observable.retryWhen method. However I am running into an issue where the error being passed to my retry method has a type of Subject instead of Response like I expected and have gotten in the past. This is an issue because I need to check if the status is a 401 and Subject doesn't include the status of the response. Also the catch works as expected passing a Response object to the handleError method.
http.service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
@Injectable()
export class HttpService {
constructor(
private http: Http
) { }
public get(url: string, headers?: Headers): Observable<any> {
return this.http.get(url, this.getHeaders(headers))
.map(this.extractData)
.retryWhen(this.handleRetry)
.catch(this.handleError);
}
private handleRetry(error: Response): Observable<any> {
if (error.status === 401) { // I can't get past here because error doesn't include status and is the wrong type.
...
}
}
}
Error equals
Subject {
closed: false
hasError: false
isStopped: false
observers: Array(0)
thrownError: null
_isScalar: false
}
While I expect error to equal something similar to:
Response {
headers: Headers
ok: false
status: 401
statusText: "OK"
type: 2
url: "..."
_body: ""
}
回答1:
The function passed to retryWhen does not receive an Error; it receives an Observable<Error> argument. That is why you are seeing a Subject.
The logic in your handleRetry function needs to be composed into an observable, from within which any effected errors can be inspected. mergeMap could be used to retry some errors and fail others. For example:
private handleRetry(errors: Observable<Response>): Observable<any> {
return errors.mergeMap(error => {
if (error.status === 401) {
// Add an authorization header, perhaps.
// ...
// Emit anything (the error instance, for example) to retry:
return Observable.of(error);
} else {
// Throw the error to give up retrying:
return Observable.throw(error);
}
});
}
来源:https://stackoverflow.com/questions/44377619/angular-2-observable-retrywhen-doesnt-include-status-in-error