2017-06-05 79 views
1

我試圖讓我的代碼更新,以便能夠使用刷新標記保持用戶登錄。我打算使用Observable.retryWhen方法執行此操作。但是,我遇到了一個問題,傳遞給我的重試方法的錯誤類型爲Subject,而不是像我期望的那樣在過去得到的Response。這是一個問題,因爲我需要檢查狀態是否爲401,並且Subject不包括響應的狀態。此外,捕獲按預期工作,將Response對象傳遞給handleError方法。Angular 2 Observable.retryWhen不包括錯誤狀態

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. 
     ... 
    } 
    } 
} 

錯誤等於

Subject { 
    closed: false 
    hasError: false 
    isStopped: false 
    observers: Array(0) 
    thrownError: null 
    _isScalar: false 
} 

雖然我預計錯誤類似於等於東西:

Response { 
    headers: Headers 
    ok: false 
    status: 401 
    statusText: "OK" 
    type: 2 
    url: "..." 
    _body: "" 
} 

回答

0

功能傳遞給retryWhen未收到Error;它收到Observable<Error>參數。這就是爲什麼你看到一個Subject

您的handleRetry函數中的邏輯需要組成一個可觀察的,可以在其中檢查任何受影響的錯誤。 mergeMap可用於重試一些錯誤並使其他人失敗。例如:

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); 
    } 
    }); 
} 
+0

嘿,我覺得你的迴應更側重於做什麼,一旦我確定error.status === 401我特意保留了這一點,因爲我知道該怎麼做一旦錯誤狀態。我的問題是爲什麼我的錯誤沒有狀態。在我可以檢查狀態之前,重試處理程序的行爲並不重要,因爲它的行爲取決於該狀態。 請將您的答案重點放在手頭的問題上,爲什麼錯誤沒有狀態,請不要擔心重試處理程序返回的內容或它的行爲除了應該有權訪問響應的狀態。 – efarley

+0

答案的關鍵在於* first *句子。你的'handleRetry'函數不*接收'Error'參數。其餘的是上下文。 – cartant

+0

它看起來像你的答案的相關位是使用mergeMap。如果你可以在這個問題上做出更簡潔的回答,我會將其標記爲正確的。正如我覺得你專注於如何使用重試時,很難找到獲取錯誤狀態所需的一行相關代碼。像「綁定」這樣的東西和返回的可觀察對象完全超出了問題的範圍,只是混淆了答案。 – efarley