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