Rxjs-如何在通知用户界面错误的同时重试出错的可观察对象 问题

Rxjs-如何在通知用户界面错误的同时重试出错的可观察对象 问题,rxjs,rxjs6,reactivex,data-layers,Rxjs,Rxjs6,Reactivex,Data Layers,假设有一个Http请求出现错误,我们可以重试。但我也希望UI通知用户该资源加载失败。什么是最好的架构 可观察目标的预期行为 可重试 长跑。不完整或错误 共享。当有多个订户时,不会生成不必要的请求 按需加载。未订阅时不会生成不必要的请求 将错误通知UI (3和4可以通过shareReplay({bufferSize:1,refCount:true})实现) 我的尝试 我认为最好在继续重试源代码的同时,将错误消息传递给下游的观察者。它对体系结构的更改最小。但是我没有看到一种方法可以用Rxjs实现,因

假设有一个Http请求出现错误,我们可以重试。但我也希望UI通知用户该资源加载失败。什么是最好的架构

可观察目标的预期行为
  • 可重试
  • 长跑。不完整或错误
  • 共享。当有多个订户时,不会生成不必要的请求
  • 按需加载。未订阅时不会生成不必要的请求
  • 将错误通知UI
  • (3和4可以通过
    shareReplay({bufferSize:1,refCount:true})
    实现)

    我的尝试 我认为最好在继续重试源代码的同时,将错误消息传递给下游的观察者。它对体系结构的更改最小。但是我没有看到一种方法可以用Rxjs实现,因为

  • retry()
    始终拦截错误。如果将错误具体化,则
    重试()
    不会重试。如果不是,则错误不会传播到下游
  • catchError()
    如果不重试,将始终完成流

  • 虽然让用户界面观察者点击(,,onError)和
    重试()
    可以满足这一需求,但我认为让用户界面承担这一责任是危险的。多个UI观察器意味着大量重复的重试。

    听起来你在寻找类似NgRx副作用的东西。您可以将其全部封装在一个外部可观察对象中,通过管道将错误处理程序连接到内部可观察对象(您的HTTP调用),如下所示:

    constmyobs$=fromEvent('placeevent,触发此处调用')。管道(
    //举个例子,你可以随意触发它
    switchMap(()=>this.myHttpService.getResource().pipe(
    catchError(err=>HandleandRetrowerRor()),
    重试(3)
    ),
    shareReplay()
    );
    

    这样,如果请求抛出错误,它将重试3次(在
    catchError
    块中进行错误处理,即使它完全出错,外部可观察对象仍然存在。这看起来有意义吗?

    嗯,我似乎在浏览文档时意外地找到了答案

    首先使用
    catchError
    的第二个参数。根据文档,
    retry
    catchError
    实现。我们可以用较低级别的
    catchError
    表达更多的逻辑

    所以只是

    catchError((err, caught) => {
      return timer(RETRY_DELAY_TIME).pipe(
        mergeMap(() => caught)
        startWith(err)
      );
    })
    

    它重试可观察对象,同时向下游观察者发送错误消息。因此,下游知道连接错误,并且可以期望接收重试值。

    如果我想分离UI和数据基础结构,我可以发送在
    HandleandRetrowerRor()中捕获的错误消息
    主题
    并让用户界面订阅
    主题
    。这是你想要的解决方案吗?这是一种方法,是的。基本上你可以在
    catchError
    块中做任何你喜欢的错误处理。谢谢。如果有更好的体系结构(我仍然觉得我的解决方案很笨拙),请让我知道。此代码将在向订阅服务器发出错误之前等待整个重试延迟时间。在我的情况下,这是20秒,因此在用户收到任何错误通知之前有很长的延迟,我们打算重试。下面是一个对我有效的替代方法(非常感谢First_Strike首先向我展示了如何做到这一点):
    catchError((err,catch)=>{return concat(of(err),timer(RETRY_DELAY_TIME)。pipe(mergeMap(()=>catch));}