RxJava-在完成之前触发另一个可观察/可完成,并仅在完成之后触发

RxJava-在完成之前触发另一个可观察/可完成,并仅在完成之后触发,java,rx-java,Java,Rx Java,我对RxJava并不完全陌生,但我被一项看似简单的任务所阻碍 我有一个数据源,它公开了一个反应式API,我所要做的就是获取一些数据,返回它,并在没有其他数据发出时自动关闭连接 这是我的密码: public Observable<Object> execute(String query) { Single<RxConnection> rxConnection = getRxDB().getConnection(); return rxConnection

我对RxJava并不完全陌生,但我被一项看似简单的任务所阻碍

我有一个数据源,它公开了一个反应式API,我所要做的就是获取一些数据,返回它,并在没有其他数据发出时自动关闭连接

这是我的密码:

public Observable<Object> execute(String query) {

    Single<RxConnection> rxConnection = getRxDB().getConnection();

    return rxConnection.flatMapObservable(conn -> {
        Observable<Object> rxResult = conn.query(query);

        return rxResult.doOnCompleted(() -> {
            conn.close(); // THIS DOES NOT WORK. I would like to close the connection and to wait without blocking.
        });

    });

}
公共可观察执行(字符串查询){
单rxConnection=getRxDB().getConnection();
返回rxConnection.flatMapObservable(连接->{
可观测rxResult=conn.query(查询);
返回rxResult.doOnCompleted(()->{
conn.close();//这不起作用。我想关闭连接并在不阻塞的情况下等待。
});
});
}
conn.query()和conn.close()在不同的调度程序中异步执行。 此代码不起作用,因为conn.close()返回一个没有订阅服务器的Completable。此外,如果我手动订阅doOnCompleted方法本身,那么rxResult Observable将在不等待连接关闭的情况下完成

我希望“execute(String query)”方法返回一个可观察的: -发出conn.query()调用获取的所有项 -当没有更多要发射的项时,它将触发conn.close() -仅在conn.close()可完成后完成


谢谢。

资源关闭是通过可观察的
来管理的。使用

Observable<T> obs = 
    Observable.using(
        resourceFactory,
        observableFactory,
        disposeAction)
可观测obs=
可观察的(
资源工厂,
可观察性,
处置)

此创建方法可确保由
资源工厂创建的资源在终止(完成或错误)或取消订阅时被处置。

资源关闭通过
可观察的方式进行管理。使用

Observable<T> obs = 
    Observable.using(
        resourceFactory,
        observableFactory,
        disposeAction)
可观测obs=
可观察的(
资源工厂,
可观察性,
处置)
此创建方法确保由
资源工厂创建的资源在终止(完成或错误)或取消订阅时被释放。

如何:

Observable<Object> rxResult = conn.query(query)
.concatWith(conn.close().toObservable())
.onErrorResumeNext(e -> 
    conn.close().toObservable().concatWith(Observable.error(e)));
Observable rxResult=conn.query(查询)
.concatWith(conn.close().toObservable())
.onErrorResumeNext(e->
conn.close().toObservable().concatWith(Observable.error(e));
那么:

Observable<Object> rxResult = conn.query(query)
.concatWith(conn.close().toObservable())
.onErrorResumeNext(e -> 
    conn.close().toObservable().concatWith(Observable.error(e)));
Observable rxResult=conn.query(查询)
.concatWith(conn.close().toObservable())
.onErrorResumeNext(e->
conn.close().toObservable().concatWith(Observable.error(e));

因此,您希望仅在可观察对象订阅时执行查询:

private Observable<Object> executeDeferred(String query) {
   // your original execute() method here, including doOnComplete
}


public Observable<Object> execute(String query) {
  return Observable.defer(() -> executeDeferred(query));
}
private Observable executeferred(字符串查询){
//这里是您最初的execute()方法,包括doOnComplete
}
公共可观察执行(字符串查询){
return Observable.defer(()->executeferred(query));
}
这将确保连接、查询和释放仅在可观察对象获得订阅时发生,而不是在安装过程中发生


编辑:您还需要一个doUnsubscribe/doInterminate,以便在过早取消订阅时关闭连接。

因此,您希望仅在可观察对象订阅时执行查询:

private Observable<Object> executeDeferred(String query) {
   // your original execute() method here, including doOnComplete
}


public Observable<Object> execute(String query) {
  return Observable.defer(() -> executeDeferred(query));
}
private Observable executeferred(字符串查询){
//这里是您最初的execute()方法,包括doOnComplete
}
公共可观察执行(字符串查询){
return Observable.defer(()->executeferred(query));
}
这将确保连接、查询和释放仅在可观察对象获得订阅时发生,而不是在安装过程中发生


编辑:您还需要DoUnSubscribe/DoInterminate,以便在过早取消订阅时关闭连接。

这是一个有趣的解决方案;然而,我不能让它工作。事实上,resourceFactory不允许返回可观察的,而只允许返回资源实例,这与我的情况不同。resourceFactory提供资源,observableFactory从资源(由resourceFactory创建)创建可观察的@akarnokd涵盖了您的具体问题的细节,但您应该使用
可观察。使用
获得适当的资源关闭。这是一个有趣的解决方案;然而,我不能让它工作。事实上,resourceFactory不允许返回可观察的,而只允许返回资源实例,这与我的情况不同。resourceFactory提供资源,observableFactory从资源(由resourceFactory创建)创建可观察的@akarnokd涵盖了您的具体问题的细节,但您应该使用
可观察。使用
获得适当的资源关闭。这似乎以一种非常简单的方式解决了我的问题。此外,它还处理可能出现的错误。然而,令人恐怖的是,rx强迫你把所有东西都转换成可观察的东西,创造出许多无用的物体。这似乎以一种非常简单的方式解决了我的问题。此外,它还处理可能出现的错误。然而,令人恐怖的是,rx强迫你把一切都转换成可观察的,创造了许多无用的物体。