【问题标题】:Unable to make a retry for API call Getting the success event无法重试 API 调用获取成功事件
【发布时间】:2021-07-21 14:54:41
【问题描述】:

我需要使用 fork-join 进行多个 API 调用,如果 3 秒后任何一个 API 调用都需要重试,即使 API 失败,我们也不应该去订阅。并且重试也应该发生一次重试就是这样 对于上述要求,我通过以下方式实现:-

const getPosts = this.api
      .get("/posts/")
      .pipe(catchError(this.getCatchError));
    const getPostsFaliure = this.api.get("/postsasdfs/")
      .pipe(catchError(this.getCatchError));
    ;
    forkJoin(getPosts, getPostsFaliure)
      .pipe(
        retryWhen(err => {
          err.pipe(
            tap(val => console.log(`Value ${val} was too high!`)),
            //restart in 6 seconds
            delayWhen(val => timer(val * 1000))
          );
        })
      )
      .subscribe(res => console.log(res));

而getCatcherror就是这样存在的:-

getCatchError(error) {
    return of(false);
  }

对于上述实现,我得到以下结果:-

[Array(100),false]

它不会进入错误,重试也对我不起作用 API 调用只进行一次,我需要限制它订阅,直到 API 通过,如果至少有一个失败我需要进入 err 部分的订阅。而且我有一个严格的规则,从 rxjs 使用重试 如何解决这个问题

Stackblitz 网址:-https://stackblitz.com/edit/angular-api-call-cpr1hk?file=src/app/app.component.ts

【问题讨论】:

  • 你应该在管道内使用 catchError 来捕获它,然后你重试逻辑
  • 所以你告诉我在重试后使用 this.getCatchError
  • ``` forkJoin(getPosts, getPostsFaliure) .pipe( retryWhen(errors => errors.pipe( delay(3000), take(3) ) ), catchError(this.getCatchError) ) .subscribe ( res => { console.log("进入 res"); }, err => { console.log("coming error"); }, () => { console.log("coming to done"); }); ```我用这种方式尝试过,但仍然在重试,但不会出错
  • 您在问题中说 3 秒,但在代码中以某种方式延迟了 6 秒。哪个是正确的要求?如果出现错误,您希望重试多少次?

标签: angular typescript rxjs rxjs-observables rxjs-pipeable-operators


【解决方案1】:

您正在使用of(false) 将错误切换为有效通知。必须删除它才能调用 retryWhen

  1. 您可以使用显式变量来表示重试尝试。
  2. catchError 块返回throwError(转发错误)或EMPTY 常量(完成observable)。
import { forkJoin, throwError, EMPTY } from 'rxjs';
import { catchError, retryWhen } from 'rxjs/operators';

const getPosts = this.api.get("/posts/");
const getPostsFaliure = this.api.get("/postsasdfs/");
let retry = 0; // max 3 allowed

forkJoin(getPosts, getPostsFaliure).pipe(
  catchError(err => {
    if (retry <= 3) {
      retry++;
      return throwError(err);
    }
    return EMPTY; // <-- complete the observable if max retries reached
  }),
  retryWhen(err => err.pipe(delay(3000)))
).subscribe(res => console.log(res));

【讨论】:

    猜你喜欢
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    • 2021-08-19
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    相关资源
    最近更新 更多