简体   繁体   English

使用Observable.interval等待远程数据或超时

[英]Using Observable.interval to wait for remote data or timeout

I need to wait for a condition or timeout. 我需要等待条件或超时。 I came up with the following approach, but there are too many things happening. 我想出了以下方法,但是发生的事情太多了。 How can i compress this. 我该如何压缩。

import io.reactivex.Observable;
import java.util.concurrent.TimeUnit;
import io.reactivex.schedulers.Schedulers;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.ThreadLocalRandom;

public class Test{
  public static void main(String[] args)throws InterruptedException{
    AtomicBoolean toggle = new 
    java.util.concurrent.atomic.AtomicBoolean(true);
    Observable.interval(0,50, TimeUnit.MILLISECONDS)
            .takeWhile(l->l<(20000/50))
            .takeWhile(l-> toggle.get())
            .observeOn(Schedulers.io())
            .map(l->{ return (l>ThreadLocalRandom.current()
                            .nextInt(5, 20 + 1))?true:false;})
             // The above map will call a remote function to check for some condition
            .observeOn(Schedulers.computation())
            .filter(exist->exist)
            //.takeWhile(exist->!exist)
            .map(l->{toggle.set(false);return l;})
            .map(l->{System.out.println("Called at "+l);return l;})
            .blockingSubscribe();
    }
}

Here is code. 这是代码。 You can use firstElement to get the first item. 您可以使用firstElement获取第一项。

import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;

import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

public class Q44234633 {
  public static void main(String[] args) throws InterruptedException {
    Observable.interval(50, TimeUnit.MILLISECONDS)
        .takeWhile(l -> l < 400)
        .observeOn(Schedulers.io())
        .filter(l -> isConditionTrue(l))
        .observeOn(Schedulers.computation())
        .firstElement()
        .doOnSuccess(System.out::println)
        .isEmpty()
        .filter(empty -> empty)
        .doOnSuccess(b -> System.out.println("TimeOut"))
        .blockingGet();
  }

  private static boolean isConditionTrue(long time) {
    return time > ThreadLocalRandom.current().nextInt(5, 20 + 1);
  }
}

There are also two tips for you. 还有两个提示给您。

  1. You can use doOnNext rather than map if you actually don't map the value. 如果您实际上不映射值,则可以使用doOnNext而不是map
  2. BooleanValue? true : false BooleanValue? true : false can be written BooleanValue directly. BooleanValue? true : false可以直接写为BooleanValue

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM