Rx java 在'重新启动时接收样本;暂停后的第一个';

Rx java 在'重新启动时接收样本;暂停后的第一个';,rx-java,Rx Java,有人能建议如何用RXJava实现这个案例吗? 它看起来像示例,但有两个区别: 样本从第一次发射开始(1),即使之前已订阅 如果两次发射之间的间隔(4和5在本例中)超过采样率(1秒),则采样将在后一次发射(5)时重新开始 这需要自定义操作员(可靠)或与现有操作员(不太可靠)组合: publicstaticvoidmain(字符串[]args)引发异常{ int[]延迟={010025030097510501200}; 可流动。范围(0,延迟。长度) .flatMap(v->Flowable.ti

有人能建议如何用RXJava实现这个案例吗?

它看起来像
示例
,但有两个区别:

  • 样本从第一次发射开始(1),即使之前已订阅
  • 如果两次发射之间的间隔(45在本例中)超过采样率(1秒),则采样将在后一次发射(5)时重新开始

  • 这需要自定义操作员(可靠)或与现有操作员(不太可靠)组合:

    publicstaticvoidmain(字符串[]args)引发异常{
    int[]延迟={010025030097510501200};
    可流动。范围(0,延迟。长度)
    .flatMap(v->Flowable.timer(延迟[v],时间单位为毫秒)
    .map(u->(v+1)+“@”+延迟[v]+“毫秒”))
    .compose(firstAndSample(200,时间单位为毫秒))
    .blockingSubscribe(System.out::println)
    ;
    }
    公共静态可流动变压器firstAndSample(长延时,时间单位){
    返回f->{
    调度程序s=新的SingleScheduler();
    返回f.publish(g->{
    返回g.take(1)
    康卡特维思先生(
    G
    .样本(延迟、单位、秒、真)
    .超时(延迟+1,单位,秒)
    )
    .重试(e->e instanceof TimeoutException)
    ;
    });
    };
    }
    

    它通过上游共享流中的相位切换工作(
    publish
    )。在第一阶段,它从上游提取1个项目,然后切换到第二阶段(
    concatWith
    )。第2阶段对上游(
    sample
    )进行采样,如果采样在其周期(
    timeout
    )之后没有发出任何东西,则子流失败,我们通过重试触发的
    TimeoutException
    再次切换到第1阶段。为确保采样和超时评估按顺序进行,这两种方法都使用了特定的单线程
    调度程序
    。(可靠性较低的原因是相变不是原子性的,因为其成分分布在多个操作符之间)。

    我认为您可以根据具体要求使用自定义操作符。您能否详细说明1)?是否要缓存任何未来订阅服务器的第一次发射?不,不需要缓存。像一个出版主题,不是行为。很好的方法,谢谢。我使用RXJava1,因此将尝试采用此示例并进行尝试。
    public static void main(String[] args) throws Exception {
        int[] delay = { 0, 100, 250, 300, 900, 975, 1050, 1200 };
    
        Flowable.range(0, delay.length)
        .flatMap(v -> Flowable.timer(delay[v], TimeUnit.MILLISECONDS)
            .map(u -> (v + 1) + " @ " + delay[v] + " ms"))
        .compose(firstAndSample(200, TimeUnit.MILLISECONDS))
        .blockingSubscribe(System.out::println)
        ;
    }
    
    public static <T> FlowableTransformer<T, T> firstAndSample(long delay, TimeUnit unit) {
        return f -> {
            Scheduler s = new SingleScheduler();
            return f.publish(g -> {
               return g.take(1)
               .concatWith(
                   g
                   .sample(delay, unit, s, true)
                   .timeout(delay + 1, unit, s)
               )
               .retry(e -> e instanceof TimeoutException)
               ;
            });
        };
    }