Angular 如何使用我的第一个自定义操作符正确扩展rxjs/Observable

Angular 如何使用我的第一个自定义操作符正确扩展rxjs/Observable,angular,rxjs,observable,ngrx,ngrx-effects,Angular,Rxjs,Observable,Ngrx,Ngrx Effects,我试图在我的服务调用中使用重试模式,实际上:@Effects在ngrx/store中,延迟间隔增加。因为我设法为一个调用找到了一个工作代码,即使它看起来没有优化,我不想在我的问题中集中讨论这个问题,我现在想将它提取到一个定制的可观察操作符中,并在我所有的服务调用中重复使用它 关于如何为新操作员设计API/用法以及如何使其被TypeScript识别,我是空白的 下面的代码肯定不起作用,因为它可能会积累大量的问题 因此,现在我有一个调用/效果如下: @影响 loadData$:Observable=

我试图在我的服务调用中使用重试模式,实际上:@Effects在ngrx/store中,延迟间隔增加。因为我设法为一个调用找到了一个工作代码,即使它看起来没有优化,我不想在我的问题中集中讨论这个问题,我现在想将它提取到一个定制的可观察操作符中,并在我所有的服务调用中重复使用它

关于如何为新操作员设计API/用法以及如何使其被TypeScript识别,我是空白的

下面的代码肯定不起作用,因为它可能会积累大量的问题

因此,现在我有一个调用/效果如下:

@影响 loadData$:Observable=this.actions$ .ofTypeActionTypes.LOAD_数据 .拔下“有效载荷” .switchMapparams=>{ 返回this.myService.getDataparams .mapres=>new LoadDataCompleteActionres //…这部分必须提取: .RetryWhenAttests=>可观察 .zipattempts,可见。范围1,5 .flatMapn,i=>{ 如果我<4{ 返回可观测时间1000*i; }否则{ 投掷; } } } .catcherr=>新加载数据的可观察值失败; 我所追求的是能够在其他效果中重用重试部分,并具有类似于以下的模式:

@影响 loadData$:Observable=this.actions$ .ofTypeActionTypes.LOAD_数据 .拔下“有效载荷” .switchMapparams=>{ 返回this.myService.getDataparams .mapres=>new LoadDataCompleteActionres .RetryWhenAttents=>Observable.retryOrThrowattempts,maxAttempts //或者——这是我的设计问题 .retryOrThrowattempts,maxAttempts } .catcherr=>新加载数据的可观察值失败; 为了简单起见,我们可以假设延迟回调模式i*1000对于整个应用程序是常数

下面的代码是我的尝试,但显然不起作用

声明模块“rxjs/Observable”{ 可观测界面{ retryOrThrowattempts:任意,最大:数量:可观察; } } Observable.prototype.retryOrThrow=功能测试测试,最大{ console.log'retryOrThrow called'; return Observable.createsubscriber=>{ const source=this; const subscription=source.subscripte=>{ //要点:从用户提供的回调捕获错误 试一试{ 订阅人 .zipattempt,可观察。范围1,最大值+1 .flatMapn,i=>{ console.logn,i; 如果我subscriber.error, =>subscriber.complete; //现在就回来 退订; }; }; 我不知道如何为新的操作符设计API,什么语法最适合这里。 我不知道如何正确地声明新操作符和可观察的名称空间或模块,以便TypeScript识别新内容。 更新服务电话:

getMocky{ 常数u=数学随机; 康斯特奥库尔酒店http://www.mocky.io/v2/58ffadf71100009b17f60044'; 常数http://www.mocky.io/v2/58ffae7f110000ba17f60046'; 返回u>0.6?this.http.getokUrl:this.http.geterUrl; }
我无法直接回答您的问题,因为我不知道如何使用自定义操作符扩展rxjs

幸运的是,你和我都不需要知道。 您真正要问的是如何预先定义一个操作符链,以便在多个位置重用

您所需要的就是这个工具,它使用起来非常简单

首先将要重用的逻辑提取到一个函数中,该函数返回一个可观察的:

函数retryOrThrowmaxAttempts,超时{ 返回源=> 来源 .RetryWhenAttests=>可观察 .zipattempts,可观察。范围1,最大尝试次数+1 .flatMapn,i=>{ 如果我尝试{ return Observable.timertimeout*i; }否则{ 投掷n; } } ; } 使用let在效果中使用函数:

@影响
loadData$:可观察到。这真的很简单,因为它所做的只是将给定的函数应用于可观测的源。

这太棒了!非常感谢你!想知道为什么他们没有在这一页上提到这个简单的方法实际上,这段代码有一个问题-当连接到主效果链时,它似乎永远不会重置尝试次数。当连接到服务调用时-它实际上从不重试调用。我将设法把这件事孤立起来。但是根据我的想法,我仍然认为答案是正确的。你能试着在let之后直接捕捉,而不是在switchMap之外吗?我认为你观察到的效果在
它击中了let@nuton的内部,我只是在一个更简单的例子中尝试了它。我认为问题在于你抓住了可观察到的效应本身。用switchMap…捕捉。。。可观察到的效果在捕获后完成。如果捕捉到switchMap的内部,效果可观察链将保持活动状态。尝试如下链接:.switchMapserviceCall.map…let…catch…我用我正在测试链接的服务调用更新了我的帖子。我已经玩了半个小时左右,看起来,尽管使用了一个随机种子,但在链的开头选择的url在所有尝试中都会保持不变。我没有一个系列的结局会在中间。要么是一系列的失败,要么是一次成功的呼叫。