Observable 错误,执行不同的 observable,重试原始 observable (Angular, RxJs6)

Posted

技术标签:

【中文标题】Observable 错误,执行不同的 observable,重试原始 observable (Angular, RxJs6)【英文标题】:Observable error, execute different observable, retry original observable (Angular, RxJs6) 【发布时间】:2020-07-23 16:20:53 【问题描述】:

我正在处理一个跨多个应用程序使用 SSO 的项目。但是,该应用程序有它自己独立的订阅服务。我们从 SSO 获取用户名和电子邮件,以创建订阅。如果订阅已经存在,我们编辑它,否则我们创建一个新的。

我正在尝试将其写在可观察的管道中以进行订阅。

基本上首先尝试编辑订阅(我们假设它存在),但是,如果由于某个错误(用户不存在)而失败 - 创建一个全新的订阅,然后返回编辑它。如果它因其他错误而失败,例如服务器错误,则只需抛出该错误。

我的问题是正确编写此逻辑。这是我所拥有的:


    this.userSubscriptionService.getSubscriptions(this.userName).pipe(
      catchError((err) => 
        if (err.error.message === 'Enter a valid username') 
          return this.userSubscriptionService.createSubscription(this.userName, this.emailAddress);
         else 
          return throwError(err);
        
      ),
      flatMap((userSubs: IUserSubscriptions) => this.editSubscription(userSubs))
    ).subscribe();

首先我获得了订阅,因此我可以使用新信息对其进行编辑。但是,如果 getSubscription 抛出错误,我想使用从单独的 SSO 服务获取的用户名和电子邮件创建订阅,然后编辑全新的订阅以包含新信息。

createSubscription 只会根据它是否有效返回一个布尔值,而 getSubscription 返回我需要的所有信息。

在我发现错误后,我无法弄清楚如何编写重试逻辑。

如果您需要信息,请告诉我..

感谢您的任何反馈。

===========================编辑==================== ===

所以最终我要解决的是,如果用户不存在,则创建用户,然后重新启动整个管道。我想出了这个


    this.userSubscriptionService.getSubscriptions(this.userName).pipe(
      catchError((err) => 
        if (err.error.message === 'Enter a valid username') 
          return this.userSubscriptionService.createSubscription(this.userName, this.emailAddress);
         else 
          return throwError(err);
        
      ),
      flatMap((userSubs: IUserSubscriptions) => this.editSubscription(userSubs)),
      retryWhen(err => 
        return err;
      ),
    ).subscribe();

哪个有效 - 除非后端已关闭或有其他一些重复出现的错误。如果错误无法解决,它将无限重试我的管道。

【问题讨论】:

所以return this.userSubscriptionService.createSubscription(this.userName, this.emailAddress); 部分有效,您只想知道当管道出错时如何重试? 你可以看看retryWhen,这需要一个接收错误的函数,如果你不想重试,你可以抛出它,或者返回另一个可观察的,当它触发重试管道。 @RobinDeSchepper 是的,if return this.userSubscriptionService.createSubscription(this.userName, this.emailAddress) 成功了,我想重试管道 @RobinDeSchepper 所以使用 retryWhen - 我发现了错误。检查错误是否有“无效用户”错误消息。如果是,则执行 createSubscription。如果 createSubscription 成功,则返回其输出,这将重试管道。否则,返回原始错误,它将抛出该错误。我的理解正确吗? 【参考方案1】:

这是我想出的答案。到目前为止,我还没有能够打破,这似乎不是一个非常糟糕的做法。但是,如果有更好的解决方案或更合适的语法,我不会感到惊讶。请指教。

this.userSubscriptionService.getSubscriptions(this.userName).pipe(
  catchError((err) => 
    if (err.error.message === 'Enter a valid username') 
      return this.userSubscriptionService.createSubscription(this.userName, this.emailAddress);
     else 
      return throwError(err);
    
  ),
  flatMap((userSubs: IUserSubscriptions) => this.editSubscription(userSubs)),
  retry(1),
).subscribe();

【讨论】:

以上是关于Observable 错误,执行不同的 observable,重试原始 observable (Angular, RxJs6)的主要内容,如果未能解决你的问题,请参考以下文章

在哪里订阅 Angular 中的 observable、构造函数或 ngoninit [关闭]

从(服务器发送的)EventSource 创建一个 RxJS Observable

自定义观察者设计模式

这种奇怪的 C++ 语法有啥作用? [复制]

RxJs 在错误时调用 observable 并重复步骤

抛出错误替代 catchErrorJustReturn 的 RxSwift Observable