Angular / RXJS-跟踪陷入重试模式的HTTP请求

Mer*_*ial 6 httprequest observable rxjs angular

我有一个为我处理多个API请求的函数,如果失败,则将每个请求置于重试模式。现在,如果一个请求已经在Retry循环中,并且同一API调用的另一个实例到达,则我的函数无法跟踪此请求,并再次在retry循环中添加冗余API调用。

Assuming i am placing a call to
/api/info/authors

What is happening

1stREQ| [re0]------>[re1]------>[re2]------>[re3]------>[re4]------>[re5]
2ndREQ|                         [re0]------>[re1]------>[re2]------>[re3]------>[re4]------>[re5]


What should happen,

1stREQ| [re0]------>[re1]------>[re2]------>[re3]------>[re4]------>[re5]
2ndREQ|                         [re0]/ (MERGE)
Run Code Online (Sandbox Code Playgroud)

以下是我的服务重试功能,

Assuming i am placing a call to
/api/info/authors

What is happening

1stREQ| [re0]------>[re1]------>[re2]------>[re3]------>[re4]------>[re5]
2ndREQ|                         [re0]------>[re1]------>[re2]------>[re3]------>[re4]------>[re5]


What should happen,

1stREQ| [re0]------>[re1]------>[re2]------>[re3]------>[re4]------>[re5]
2ndREQ|                         [re0]/ (MERGE)
Run Code Online (Sandbox Code Playgroud)

注意:

有人提出了建议shareReplay(),因此我尝试实现它,但是它无法处理来自其他两个组件/源的相同请求。

紧随其后的应该是6,而不是在快速调用两个调用相同API的按钮(缩放持续时间为1000ms)时为12。

在此处输入图片说明

注意:

FLAGS在我看来,请避免使用它是最终的核武器。

Val*_*kov 1

请注意,每次调用getInfoAPI() http.get()都会创建一个新的可观察值,并shareReplay()共享该新的可观察值,它不会合并两个调用。如果您希望调用者获得合并的可观察量,则可以从两次调用中返回相同的可观察量。但这是错误的解决方案,我稍后会解释。例如:

export class DataService {
  private readonly getInfoRequest = new Subject<GetInfoRequest>();
  private readonly getInfoResponse = this.getInfoRequest.pipe(
    exhaustMap(request => { 
      const callURL = createGetInfoUrl(request);
      const callParams = createGetInfoParams(request);
      return this.http.get(callURL, callParams).pipe(
        retryWhen( ... );
      );
    })
  );

  public getInfoAPI(category:string, id:string = "", page:string = "1", limit:string = "10") {
    this.getInfoRequest.next({ category: category, id: id, page: page, limit: limit });
    return this.getInfoResponse;
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

上面的代码执行相同的操作,您尝试通过 实现shareReplay(),但是如果调用参数不匹配怎么办?一个组件请求了第一页,但另一个组件请求了第二页,第二个组件将接收第一页而不是第二页。所以,我们也应该考虑调用参数,事情变得更加复杂。

一个解决方案可能是用存储库包装 HttpService,它将处理缓存,它可以将数据缓存在内存中、数据库内或其他地方,但我怀疑这是否是您想要的。据我了解问题是并发请求,更好的方法是阻止此类请求。例如,如果请求是通过单击按钮触发的,则只需在请求执行时禁用该按钮,或者跳过重复的请求。这是解决此类问题的常用方法。