[英]RxJava 2 Observable that onComplete resubmits itself
I'm new with RxJava. 我是RxJava的新手。 I'm trying to create an observable that when it completes it will start all over again until I call dispose, but I'm facing an OutofMemory error after a while, below is a simplified example of what I'm trying to do 我正在尝试创建一个可观察的对象,当它完成时它将重新开始直到我调用dispose,但是过一会儿我遇到了OutofMemory错误,下面是我正在尝试做的一个简化示例
public void start() throws RuntimeException {
log.info("\t * Starting {} Managed Service...", getClass().getSimpleName());
try {
executeObserve();
log.info("\t * Starting {} Managed Service...OK!", getClass().getSimpleName());
} catch (Exception e) {
log.info("Managed Service {} FAILED! Reason is {} ", getClass().getSimpleName(), e.getMessage(), e);
}
}
start is invoked at the initialization phase once, the executeObserve is as follows (in a simplified form..). 一旦在初始化阶段调用了start ,则executeObserve如下(以简化形式..)。 Notice that on the onComplete I "resubmit" executeObserve 请注意,在onComplete上,我“重新提交”了executeObserve
public void executeObserve() throws RuntimeException {
Observable<Book> booksObserve
= manager.getAsObservable();
booksObserve
.map(Book::getAllOrders)
.flatMap(Observable::fromIterable)
.toList()
.subscribeOn(Schedulers.io())
.subscribe(collectedISBN ->
Observable.fromIterable(collectedISBN)
.buffer(10)
// ...some more steps here...
.toList()
.toObservable()
// resubmit
.doOnComplete(this::executeObserve)
.subscribe(validISBN -> {
// do something with the valid ones
})
)
);
}
My guess is that this is not the way to go if I want to resubmit my tasks but it was not possible to find any documentation. 我的猜测是,如果我想重新提交任务,这不是可行的方法,但是找不到任何文档。
the booksObserve is implemented as follows booksObserve的实现如下
public Observable<Book> getAsObservable() {
return Observable.create(e -> {
try (CloseableResultSet<Book> rs = (CloseableResultSet<Book>) datasource.retrieveAll())) {
for (Book r : rs) {
e.onNext(r);
}
e.onComplete();
} catch (Exception ex) {
e.onError(ex);
}
});
}
What is the correct way to constantly resubmit an operation until we call dispose or equivalent? 不断调用操作直到我们称之为Dispose或等效操作的正确方法是什么? I'm using RxJava 2 我正在使用RxJava 2
You have created an endless recursion, the loop will create more and more resources and sometime it will blow with OutOfMemory/Stack overflow exception. 您已经创建了一个无限的递归,该循环将创建越来越多的资源,并且有时会因OutOfMemory / Stack溢出异常而中断。
In order to repeat the Observable
work you should use repeat()
operator, it will resubscribes to the Observable
when it receives onComplete()
. 为了重复Observable
工作,您应该使用repeat()
运算符,当它接收onComplete()
时,它将重新订阅Observable
。
Besides that, some general comments on your code: 除此之外,对您的代码的一些一般注释:
Observable
inside the subscriber? 为什么在订户内部嵌套第二个Observable
? you are breaking the chain, you can just continue the chain instead of creating new Observable
at the Subscriber. 您正在打破链条,则可以继续链条,而不用在订阅服务器上创建新的Observable
。 Moreover, it's seems (assuming O bservable.fromIterable(collectedBets)
using the collectedISBN
that gets with the onNext()
ow from where does it comes?) you're collecting all items to a list, and then flatting it again using from iterable, so it's seems you can just continue on the stream , something like that: 此外,它似乎(假设Ö bservable.fromIterable(collectedBets)
使用collectedISBN
,与获得onNext()
你收集的所有项目的列表,然后从迭代再次使用消光流是从哪里不来?)所以看来您可以继续播放,例如:
booksObserve .map(Book::getAllOrders) .flatMap(Observable::fromIterable) .buffer(10) // ...some more steps here... .toList() .toObservable() // resubmit .doOnComplete(this::executeObserve) .subscribeOn(Schedulers.io()) .subscribe(validISBN -> { // do something with the valid ones });
Anyhow, with the nested Observable
, the repeat()
operator will just repeat the nested one, and not the entire stream (which is what you want) as it is not connected to it. 无论如何,使用嵌套的Observable
, repeat()
运算符将只重复嵌套的一个,而不是整个流(您想要的),因为它没有连接到它。
In continuation to my question the repeat
as @yosriz suggested is the proper way to go, the following simple snippet demonstrates that the observable source will be called on each repeat 在继续我的问题时,如@yosriz所建议的repeat
是正确的方法,下面的简单代码段演示了每次重复都会调用可观察到的源
Observable<Integer> recursiveObservable = Observable.create(emitter -> {
System.out.println("Calling to emit data");
Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0).forEach(emitter::onNext);
emitter.onComplete();
});
recursiveObservable
.buffer(2)
.repeat()
.subscribe(integers -> {
System.out.println(integers);
TimeUnit.SECONDS.sleep(1);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.