HTTP-запрос повторяется при определенной ошибке с использованием перехватчика и повторных попыток - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть служба, которая вызывает GET API и получает ответ обратно. Я реализовал HTTP Interceptor, чтобы правильно и глобально обрабатывать любые ошибки, возникающие в приложении. Я хочу сделать, чтобы, когда мой API возвращал конкретную ошибку, например, ошибку 501, мне нужно повторять этот запрос n раз и t секунд задержки перед каждым запросом. Я также хочу обработать общую ошибку, если мои повторные попытки завершены (то есть, если я получаю ошибку при последней повторной попытке, я хочу обработать ее определенным образом). Пожалуйста, помогите разобраться, как решить эту проблему.

Все это реализовано с использованием Angular 6, решение с правильным синтаксисом будет оценено.

Спасибо

1 Ответ

0 голосов
/ 14 ноября 2018

Вы можете сделать это, используя retryWhen, delay, tap, scan RxJS.Что-то вроде следующего кода, где служба Angular вызывает API Google для аутентификации пользователя в приложении, которое не запускается в браузере, например, в приложении для ПК.Эта служба использует RxJS для повторения вызовов API REST через определенный интервал в случае сбоя из-за нестабильного подключения к Интернету:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { retryWhen, delay, tap, scan, concatMap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class GoogleDeviceAuthService {

  private readonly client_id = "<client-id>";
  private readonly client_secret = "<client-secret>";

  private readonly userCodeRequest = {
    "client_id": this.client_id,
    "scope": "email profile"
  };

  private readonly pollGoogleAuthServerRequestTemplate = {
    "client_id": this.client_id,
    "client_secret": this.client_secret,
    "code": "",
    "grant_type": "http://oauth.net/grant_type/device/1.0"
  }

  private readonly userCodeUrl = "https://accounts.google.com/o/oauth2/device/code";

  private readonly pollGoogleAuthServerUrl = "https://www.googleapis.com/oauth2/v4/token";

  constructor(private readonly http: HttpClient) { }

  public getUserCode() {
    return this.http.post(this.userCodeUrl, this.userCodeRequest)
      .pipe(
        retryWhen(err => err.pipe(
          scan(
            (retryCount, err) => {
              if (retryCount > 3)
                throw err;
              else
                return retryCount + 1;
            }, 0
          ),
          delay(1000),
          tap(err => console.log("Retrying...", err))
        )));
  }

  public checkAuthServerForUserInput(deviceCode) {
    let pollGoogleAuthServerRequest = { 
        ...this.pollGoogleAuthServerRequestTemplate, 
        ...{ "code": deviceCode } };
    return this.http.post(this.pollGoogleAuthServerUrl, pollGoogleAuthServerRequest)
      .pipe(
        retryWhen(err => err.pipe(
          scan(
            (retryCount, err) => {
              if (retryCount > 3)
                throw err;
              else
                return retryCount + 1;
            }, 0
          ),
          delay(1000),
          tap(err => console.log("Retrying...", err))
        )));;
  }
}
...