RxJava使用新的可观察对象进行无限重试

RxJava使用新的可观察对象进行无限重试,java,rx-java,control-flow,vert.x,event-bus,Java,Rx Java,Control Flow,Vert.x,Event Bus,我使用的是vertx的Rx API,这个问题可能需要无限次重试,直到我想要实现成功循环,但我遇到了困难。我是RxJava新手 以下是我想做的: 使用vertx消息向另一个vertx组件发送请求 公共汽车 只要我得到一个等待响应的超时时间,就重新发出 请求 一旦我对请求有了响应,请检查 结果,如果没有可用的,请等待一段时间,然后重试 在第1步重新开始) 第一个问题 我遇到的第一个问题是如何完成步骤2) 如果您熟悉vert.x Rx api,这就是在上述步骤1)中发出请求的含义: vertx.eve

我使用的是vertx的Rx API,这个问题可能需要无限次重试,直到我想要实现成功循环,但我遇到了困难。我是RxJava新手

以下是我想做的:

  • 使用vertx消息向另一个vertx组件发送请求 公共汽车
  • 只要我得到一个等待响应的超时时间,就重新发出 请求
  • 一旦我对请求有了响应,请检查 结果,如果没有可用的,请等待一段时间,然后重试 在第1步重新开始)
  • 第一个问题 我遇到的第一个问题是如何完成步骤2)

    如果您熟悉vert.x Rx api,这就是在上述步骤1)中发出请求的含义:

    vertx.eventBus().sendObservable(“地址”,aJsonObject);
    
    上面的代码返回一个可观察的实例,该实例将发出响应或错误(例如,如果有超时)。那个可观测的东西永远不会再发射任何东西(或者每次有东西订阅时,它总是发射完全相同的东西,我不知道是哪个)

    RxJava重试运算符似乎不起作用
    vertx.eventBus().sendObservable(“地址”,aJsonObject)
    .重试()
    
    我认为为了发出重试,我可以使用RxJava的retry()操作符,我已经尝试过了,但是这样做完全没有任何有用的效果,因为可以观察到的源的性质。不会发送新的请求消息,因为唯一被“重试”的是对原始源的订阅,它永远不会发出任何不同的消息

    RxJava retryWhen运算符似乎不起作用
    vertx.eventBus().sendObservable(“地址”,aJsonObject)
    .retryWhen(错误->{
    return _vertx.eventBus().sendObservable(“地址”,aJsonObject)
    })
    
    然后我想我可以使用RxJava的retryWhen()操作符,它允许我在根observate发出错误时发出第二个observate。我认为,第二个可观察到的可能就是上面在步骤1中生成初始观察者的代码

    但是,retryWhen()运算符()不允许第二个可观察对象在不以错误结束订阅的情况下发出错误

    因此,我很难弄清楚如何在这个链的第一部分中设置一个潜在的无限重试循环

    我一定是遗漏了什么,但我还不能确定是什么

    第二个问题
    vertx.eventBus().sendObservable(“地址”,aJsonObject)
    //假设retryWhen()完成了无限次重试
    .retryWhen(错误->{
    返回_vertx.eventBus().sendObservable(…)
    })
    .flatMap(响应->{
    //检查响应,如果它有可用的数据,
    //将该数据作为可观察数据返回
    返回Observable.from(response.data());
    //如果响应没有可用的数据,
    //等待一段时间,然后开始整个过程
    //又一次
    返回可观察计时器(timeToWait)。;
    })
    
    第二个问题是如何实现步骤3。在我看来,这与第一个问题类似,只是更难理解,因为我不需要重试立即观察到的源代码,我需要等待一段时间,然后在步骤1)重新开始

    无论我创建什么样的可观察对象,似乎都需要指向这一点的链中的所有元素,这似乎是一种应该避免的递归


    在这一点上,任何帮助或建议都是非常受欢迎的。

    非常感谢Ben Christensen在上面指出了defer()操作符,它将在每个订阅上生成一个新的可观察对象。然后,可以使用标准的retry()运算符组合此函数,以获得有限的重试

    因此,我问题中第一个问题的最简单解决方案如下所示:

    Observable.defer( () -> vertx.eventBus().<JsonObject>sendObservable( "theAddress", aJsonObject ) )
    .retry()
    
    Observable.defer(()->vertx.eventBus().sendObservable(“地址”,aJsonObject))
    .重试()
    
    …如果需要指数退避,则可以在工厂方法中添加Observable.timer(),并将适当的参数提供给defer()运算符


    我仍在研究第二个问题。

    您是否订阅了重试()的结果?是。抱歉-示例中未显示subscribe调用。
    vertx.eventBus().<JsonObject>sendObservable( "theAddress", aJsonObject )
         .retry()
    
    vertx.eventBus().<JsonObject>sendObservable( "theAddress", aJsonObject )
         .retryWhen( error -> {
            return _vertx.eventBus().<JsonObject>sendObservable( "theAddress", aJsonObject )
          })
    
    vertx.eventBus().<JsonObject>sendObservable( "theAddress", aJsonObject )
         // imagine that retryWhen() accomplishes an infinite retry
         .retryWhen( error -> {
            return _vertx.eventBus().<JsonObject>sendObservable( ... )
          })
         .flatMap( response -> {
            // inspect response, if it has usable data,
            // return that data as an observable
            return Observable.from(response.data());
    
            // if the response has no usable data,
            // wait for some time, then start the whole process
            // all over again
            return Observable.timer(timeToWait).<WHAT GOES HERE?>;
         })
    
    Observable.defer( () -> vertx.eventBus().<JsonObject>sendObservable( "theAddress", aJsonObject ) )
    .retry()