RxJでアクションを実行した後、オブザーバブルを再試行するにはどうすればよいですか?

スパイク

Angular 2とRxJSを使用して、APIレイヤーからデータを取得しています。HTTPリクエストを処理するために作成した基本サービスがあります。次のコードは私のサービス内でこれを行います:

protected apiGet(uri: string): Observable<HttpMappedResponse<T>> {
    return this.mapAndHandle<T>(this.http.get(uri));
}

private mapAndHandle<T>(observable: Observable<Response>): Observable<HttpMappedResponse<T>> {
    const o = observable
        .map(res => {
            const data = res.json() || {};
            const mappedResponse = new HttpMappedResponse<T>(res, data);
            // Retrieve page information from HTTP headers
            mappedResponse.pageInfo = new PageInfo(res.headers);
            return mappedResponse;
        })
        .share();

    o.subscribe(null, e => this.errorService.handleHttpResponse(e));
    return o;
}

これはうまく機能し、電話をかけるときに必要なすべてのデータを取得しますapiGet()私が今やろうとしていることは次のとおりです。

  • HTTPリクエストを送信する
  • 特定の文字列で401エラーが返された場合:
    • 別のURLに別のリクエストを送信する
    • 別のサービスを更新する
    • 元のリクエストを再試行してください
    • (次に、可能な無限の再試行を処理するロジックを追加します)
  • そうしないと
    • 元のhttpエラーを再スローします
  • エラーをキャプチャして処理します

.catch()、. retryWhen()、. map()、および.flatMapTo()を使用しようとしましたが、成功しませんでした。最も近いのは次のとおりです。

enum HttpVerb {
    Put,
    Post,
    Get,
    Delete
}

private mapAndHandle<T>(uri: string, type: HttpVerb): Observable<HttpMappedResponse<T>> {
    const restObservable = this.getRestObservable(uri, type);

    const o = restObservable
        .map(res => this.mapToHttpMappedResponse<T>(res))
        .catch((error, sourceObservable) => {
            const data = error.json() || {};

            if (error.status === 401 && data.Message === 'Token expired') {
                console.log('Retrying');
                // Refresh the expired auth token
                const refreshToken = this.authService.userData.RefreshToken;
                console.log(refreshToken);

                this.authService
                    .refresh(new RefreshRequestModel(refreshToken))
                    .subscribe(x => null);

                // Retry original
                return this
                    .getRestObservable(uri, type)
                    .map(x => this.mapToHttpMappedResponse(x));
            }
            throw error;
        })
        .share();

    o.subscribe(null, e => {
        this.errorService.handleHttpResponse(e);
    });
    return o;
}

private mapToHttpMappedResponse<T>(res: Response): HttpMappedResponse<T> {
    console.log('Attempt ' + Date.now());
    const data = res.json() || {};
    const mappedResponse = new HttpMappedResponse<T>(res, data);
    // Retrieve page information from HTTP headers
    mappedResponse.pageInfo = new PageInfo(res.headers);
    return mappedResponse;
}

しかし、これは私に正しい結果を与えません。

これを行うために使用できる演算子はありますか?tryWhen()が最も論理的であるように見えますが、私はRxJで混乱し続けています!

ランサナカマラ

あなたが抱えている問題の1つは、通話を連鎖させていないことです。更新呼び出しは再試行呼び出しにチェーンされている必要flatMapがあり、同じ監視可能なストリームに保持するために、または同様のものを活用する必要があります。


この質問に対する私の答え見てください

これがあなたがそれを達成する方法です:

catchRxJSから演算子を追加する必要があります。これはエラーが発生する場所であり、それに応じて処理できます。

更新ロジックがインターセプターを通過するようにするには、呼び出しを返す必要があり、関数もを返す必要がありObservableます。たとえば、上記の元のロジックを変更します。

this.http.request(url, options)
        .map((res: Response) => res.json())
        .catch((error: any) => {
            const err = error.json();

            // Refresh JWT
            if (err.status === 401) {
                // refreshToken makes another HTTP call and returns an Observable.
                return this.refreshToken(...);
            }

            return Observable.throw(err);
        });

元のリクエストを再試行できるようにする場合は、元のリクエストデータを渡して、トークンが正常に更新されたときに再度呼び出しを行えるようにすることができます。たとえば、これはrefreshToken関数がどのように見えるかです。

refreshToken(url: string, options: RequestOptionsArgs, body: any, tokenData: any): Observable<any>
    return this.post(`${this.url}/token/refresh`, tokenData)
        .flatMap((res: any) => {
            // May want to use response data to set new tokens in your local storage or whatever here...

            // This is where I retry the original request
            return this.request(url, options, body);
        });
}

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

(Tkinter)オブジェクトを配置した後にアニメーションを実行するにはどうすればよいですか?

分類Dev

オブザーバブルをペアでバッファリングし、ペアで実行するにはどうすればよいですか?

分類Dev

タイムアウト時にIOアクションのブロックを再試行するにはどうすればよいですか?

分類Dev

ユーザーアクションを記録してからJavaScriptで再実行するにはどうすればよいですか?

分類Dev

iOSのテーブルビューでセクションを選択した後、いくつかのアクションを実行するにはどうすればよいですか?

分類Dev

ActiveJobとSidekiqで失敗したジョブの再試行カウンターを制限するにはどうすればよいですか?

分類Dev

RxJSオブザーバブルを使用してオブザーバブルが戻った後にアクションを実行する場合の「do」と「finally」の違いは何ですか?

分類Dev

Githubアクションのワークフローが終了した後にGitHubWebhookを実行するにはどうすればよいですか?

分類Dev

アクションをX回実行したユーザーを特定するにはどうすればよいですか?[keen-io]

分類Dev

BehaviourSubjectにサブスクライブしたときに、オブザーバブル内でプロミスを2回実行しないようにするにはどうすればよいですか?

分類Dev

Githubアクションを再実行するにはどうすればよいですか?

分類Dev

テストアノテーションの追加を再試行しないようにするにはどうすればよいですか?

分類Dev

最後のセッションが存在した後、tmuxサーバーを実行したままにするにはどうすればよいですか?

分類Dev

ユーザーが画面に触れるたびにQmlでアクションを実行するにはどうすればよいですか?

分類Dev

ターミナルを閉じた後もアプリケーションを実行し続けるにはどうすればよいですか?

分類Dev

終了後にジョブを再実行するにはどうすればよいですか?

分類Dev

オブザーバブルが例外をスローした場合にストリームを続行するにはどうすればよいですか?

分類Dev

Visual Studio 2015で最後のバージョンを取得した後にgulpファイルを実行するにはどうすればよいですか?

分類Dev

ユーザーアクション(終了したクエリ)をテーブルに保存するにはどうすればよいですか?

分類Dev

Angular 2でデータバインド後にアクションを実行するにはどうすればよいですか?

分類Dev

RxJSオブザーバブルパイプに、元のオブザーバブルのエミッションとパイプの以前のエミッションへのアクセスを許可するにはどうすればよいですか?

分類Dev

'merge'を使用して、オブザーバブルのリストの同時実行を制限するにはどうすればよいですか?ただし、すべてのオブザーバブルが完了した後にのみ戻りますか?

分類Dev

すべてのサブフォルダー内のすべてのpngファイルを反復処理してアクションを実行するバッチスクリプトを作成するにはどうすればよいですか?

分類Dev

ユーザーがテキストフィールドにデータを入力し終えた直後にアクションを実行するにはどうすればよいですか?

分類Dev

ジョブの実行中にデータをJobDataMapに保存し、後でアクセスするにはどうすればよいですか?

分類Dev

def __init __(self)関数を実行した後、クラスオブジェクトにデータを追加するにはどうすればよいですか?

分類Dev

ユーザーがiOSサブスクリプションで請求の再試行を入力した場合、どのようなアクションを実行する必要がありますか?

分類Dev

特定のオブザーバブルが値を放出するときにタップ演算子を実行するにはどうすればよいですか?

分類Dev

UIを介してGitLabでパイプライン(個々のジョブではない)を再試行するにはどうすればよいですか?

Related 関連記事

  1. 1

    (Tkinter)オブジェクトを配置した後にアニメーションを実行するにはどうすればよいですか?

  2. 2

    オブザーバブルをペアでバッファリングし、ペアで実行するにはどうすればよいですか?

  3. 3

    タイムアウト時にIOアクションのブロックを再試行するにはどうすればよいですか?

  4. 4

    ユーザーアクションを記録してからJavaScriptで再実行するにはどうすればよいですか?

  5. 5

    iOSのテーブルビューでセクションを選択した後、いくつかのアクションを実行するにはどうすればよいですか?

  6. 6

    ActiveJobとSidekiqで失敗したジョブの再試行カウンターを制限するにはどうすればよいですか?

  7. 7

    RxJSオブザーバブルを使用してオブザーバブルが戻った後にアクションを実行する場合の「do」と「finally」の違いは何ですか?

  8. 8

    Githubアクションのワークフローが終了した後にGitHubWebhookを実行するにはどうすればよいですか?

  9. 9

    アクションをX回実行したユーザーを特定するにはどうすればよいですか?[keen-io]

  10. 10

    BehaviourSubjectにサブスクライブしたときに、オブザーバブル内でプロミスを2回実行しないようにするにはどうすればよいですか?

  11. 11

    Githubアクションを再実行するにはどうすればよいですか?

  12. 12

    テストアノテーションの追加を再試行しないようにするにはどうすればよいですか?

  13. 13

    最後のセッションが存在した後、tmuxサーバーを実行したままにするにはどうすればよいですか?

  14. 14

    ユーザーが画面に触れるたびにQmlでアクションを実行するにはどうすればよいですか?

  15. 15

    ターミナルを閉じた後もアプリケーションを実行し続けるにはどうすればよいですか?

  16. 16

    終了後にジョブを再実行するにはどうすればよいですか?

  17. 17

    オブザーバブルが例外をスローした場合にストリームを続行するにはどうすればよいですか?

  18. 18

    Visual Studio 2015で最後のバージョンを取得した後にgulpファイルを実行するにはどうすればよいですか?

  19. 19

    ユーザーアクション(終了したクエリ)をテーブルに保存するにはどうすればよいですか?

  20. 20

    Angular 2でデータバインド後にアクションを実行するにはどうすればよいですか?

  21. 21

    RxJSオブザーバブルパイプに、元のオブザーバブルのエミッションとパイプの以前のエミッションへのアクセスを許可するにはどうすればよいですか?

  22. 22

    'merge'を使用して、オブザーバブルのリストの同時実行を制限するにはどうすればよいですか?ただし、すべてのオブザーバブルが完了した後にのみ戻りますか?

  23. 23

    すべてのサブフォルダー内のすべてのpngファイルを反復処理してアクションを実行するバッチスクリプトを作成するにはどうすればよいですか?

  24. 24

    ユーザーがテキストフィールドにデータを入力し終えた直後にアクションを実行するにはどうすればよいですか?

  25. 25

    ジョブの実行中にデータをJobDataMapに保存し、後でアクセスするにはどうすればよいですか?

  26. 26

    def __init __(self)関数を実行した後、クラスオブジェクトにデータを追加するにはどうすればよいですか?

  27. 27

    ユーザーがiOSサブスクリプションで請求の再試行を入力した場合、どのようなアクションを実行する必要がありますか?

  28. 28

    特定のオブザーバブルが値を放出するときにタップ演算子を実行するにはどうすればよいですか?

  29. 29

    UIを介してGitLabでパイプライン(個々のジョブではない)を再試行するにはどうすればよいですか?

ホットタグ

アーカイブ