代码之家  ›  专栏  ›  技术社区  ›  Var

如何在角度上重试api调用3次,直到得到数据(只有1个api,不是http拦截器的通用)

  •  0
  • Var  · 技术社区  · 4 年前

    在我的应用程序模块中,我已呼叫此提供商

    export function appConfigFactory(configService: AppConfig) {
      return () => configService.getEasyAuthToken();
    }
     { provide: APP_INITIALIZER, useFactory: appConfigFactory, deps: [AppConfig],  multi: true }
    

    AppConfig文件如下所示:

    @Injectable({
      providedIn: 'root'
    })
    export class AppConfig {
      public settings: any = null;
      public initialized = "authentication in progress";
      constructor(private httpClient: HttpClient) {
    
      }
    
      public getEasyAuthToken() {
        let aHeaders = new HttpHeaders().set('Content-Type', 'application/json');
        const url = '/.auth/me';
        console.log(`on app load ${url} called`);
        return this.httpClient
          .get<any>(url, { headers: aHeaders })
          .pipe(
            tap((config: any) => {
              console.log(config);
    
            }).error(this.initialized = "authentication failed";)
          )
          .toPromise();
      }
    }
    

    (此处是/.auth/me的其他信息=> https://docs.microsoft.com/en-us/azure/app-service/app-service-authentication-how-to#access-user-claims

    问题2:如何用管道在上面的调用中写入失败或错误块?

    问题3:当调用失败或在3次api调用后响应为空时,我希望在中显示不同的文本,例如“身份验证失败”app.component.html. -通过 this.initialized

    0 回复  |  直到 4 年前
        1
  •  0
  •   Fan Cheung    4 年前

    你可以试试用 retry(num)

    return this.httpClient
          .get<any>(url, { headers: aHeaders })
          .pipe(
            tap((config: any) => {
               if(!config.length) {
                 this.initialized = "authentication failed";
                 throw 'authentication failed';
               }
            }),
            retry(3)
          )
          .toPromise();
    
        2
  •  0
  •   Ivan A.    4 年前

    这里有一个更复杂但更灵活的解决方案:

      public getEasyAuthToken() {
        //...
        const url = '/.auth/me';
        console.log(`on app load ${url} called`);
        return this.httpClient
          .get<any>(url)
          .pipe(
            map(res => {
              if (!res) // or other check if your responce is empty
              {
                // error will be picked up by retryWhen
                throw res;
              }
              return res;
            }),
            retryWhen(errors =>
              errors.pipe(
                mergeMap((err, i) => {
                  console.log(err, i);
                  const retryAttempt = i + 1;
    
                  if (retryAttempt > this.maxRetryAttempts) {
                    // Maximum number of retries reached
                    this.initialized = "authentication failed";
                    return throwError(err);
                  }
    
                  return timer(retryAttempt * 1000);
                  }),
              )
            ),
            catchError(error => {
              // Use catchError to prevent breaking of your observable sequence
              console.error(error);
              return of(error);
              })
          )
          .toPromise();
      }
    }
    

    你可以在这里玩: https://stackblitz.com/edit/angular-z83mdi