RxJava 2可观察到onComplete重新提交自身

时间:2017-03-19 18:16:03

标签: java observable rx-java2

我是RxJava的新手。我正在尝试创建一个observable,当它完成时它将重新开始直到我调用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 ,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
                      })
             )
        );
    }

我的猜测是,如果我想重新提交我的任务,但这是不可取的,但是找不到任何文档。

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);
        }
    });
}

在我们调用dispose或同等程序之前,不断重新提交操作的正确方法是什么?我正在使用RxJava 2

2 个答案:

答案 0 :(得分:2)

你创建了一个无休止的递归,循环将创建越来越多的资源,有时候会出现OutOfMemory / Stack溢出异常。

为了重复Observable工作,您应该使用repeat()运算符,它会在收到Observable时重新订阅onComplete()

除此之外,还有一些关于代码的一般性评论:

  • 为什么要在订阅者中嵌套第二个Observable?您正在打破链条,您可以继续链而不是在订阅服务器上创建新的Observable
  • 此外,似乎(假设O bservable.fromIterable(collectedBets)使用collectedISBN来自onNext() ow来自哪里?)你正在收集所有项目到列表,然后使用可迭代再次展平它,所以看起来你可以继续在流上,类似的东西:

    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
        });       
    
  • 无论如何,对于嵌套的Observablerepeat()运算符将只重复嵌套的运算符,而不是整个流(这是你想要的),因为它没有连接到它

答案 1 :(得分:0)

继续我的问题{@ 1}} @yosriz建议是正确的方法,下面的简单片段演示了每次重复时都会调用可观察的源

repeat