我希望我的代码重复执行某个异步操作,直到此操作成功(即,直到返回true
)为止。
目前,我正在使用以下解决方法:
Supplier<Observable<Boolean>> myOperation = () -> {
// do something useful and return 'true' if it was successful
// NOTE: GENERATING A RANDOM NUMBER IS JUST AN EXAMPLE HERE
// I WANT TO RUN AN ASYNCHRONOUS OPERATION (LIKE PINGING A SERVER
// OR THE LIKE) AND RETRY IT UNTIL IT SUCCEEDS.
System.out.println("Try");
return Observable.just(Math.random() > 0.9);
};
final Throwable retry = new IllegalStateException();
Observable.<Boolean>create(subscriber -> {
myOperation.get().subscribe(subscriber);
}).flatMap(b -> b ? Observable.just(b) : Observable.error(retry))
.retryWhen(exceptions -> exceptions.flatMap(exception -> {
if (exception == retry) {
return Observable.timer(1, TimeUnit.SECONDS);
}
return Observable.error(exception);
}))
.toBlocking()
.forEach(b -> {
System.out.println("Connected.");
});
它运作良好,并打印出如下内容:
Try
Try
...
Try
Connected.
该代码可以实现我想要的功能,但是看起来并不优雅。我相信肯定有更好的方法。也许通过使用自定义
Operator
?有人知道如何在RxJava中以更易读的方式并且没有人为的
Throwable
来实现相同的目的吗? 最佳答案
没有足够的时间,所以这将取决于内存...
public class Randomizer implements Iterable<Double>, Iterator<Double> {
public Iterator<Double> getIterator() {return this;}
public boolean hasNext() {return true;}
public Double next() {return Math.random();}
}
...
Observable.from(new Randomizer())
.takeWhile(value -> value < 0.99);
// or takeUntil(value -> value > 0.99); can't remember their differences.
OTOH如果需要执行更复杂的操作,请查看
Observable.defer()
和/或BehaviorSubject
。编辑:现在有更多的时间来阅读您的文章,您可以尝试这样的事情:
Observable.defer(() -> createConnectionObservable())
.retry((count, err) -> {
if(count>9) return false;
if(!(err instanceof IOException)) return false;
return true;
})
请记住,如果您使用Retrofit,则不需要defer(),因为当发生新的订阅时,retrofit将重新启动呼叫。
关于java - 循环直到RxJava中的条件变为真,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38781907/