Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 等待并行接收用户完成_Java_Reactive Programming_Rx Java - Fatal编程技术网

Java 等待并行接收用户完成

Java 等待并行接收用户完成,java,reactive-programming,rx-java,Java,Reactive Programming,Rx Java,我正在寻找在RXJava中等待异步任务完成的最佳方法 一个常见的例子是,有一个函数从本地存储获取id列表,然后向远程系统查询这些id,然后将远程系统结果合并到单个报告中,并返回给函数的调用方。由于对远程系统的调用很慢,我们希望它们以异步方式完成,我只希望在所有调用都返回并处理其结果后返回 我发现唯一可靠的方法是对订阅进行轮询,检查它是否已取消订阅。但我认为这似乎不是“RX”的做事方式 作为一个例子,我从中选取了这个例子,并对其进行了轻微的修改,使其成为非android的,以说明我的意思。我必须在

我正在寻找在RXJava中等待异步任务完成的最佳方法

一个常见的例子是,有一个函数从本地存储获取id列表,然后向远程系统查询这些id,然后将远程系统结果合并到单个报告中,并返回给函数的调用方。由于对远程系统的调用很慢,我们希望它们以异步方式完成,我只希望在所有调用都返回并处理其结果后返回

我发现唯一可靠的方法是对订阅进行轮询,检查它是否已取消订阅。但我认为这似乎不是“RX”的做事方式

作为一个例子,我从中选取了这个例子,并对其进行了轻微的修改,使其成为非android的,以说明我的意思。我必须在main()方法的末尾编写以下代码,以立即阻止它退出

while (!subscription.isUnsubscribed()) {
    Thread.sleep(100);
}
下面列出了示例的完整代码(这取决于您是否尝试编译它)

package org.examples;
进口改装.RestAdapter;
导入reformation.http.GET;
导入reformation.http.Query;
进口接收。可观察;
输入接收用户;
进口接收订阅;
导入rx.functions.Action0;
导入rx.functions.Action1;
导入rx.functions.Func1;
导入rx.schedulers.schedulers;
公共类异步示例{
公共静态void main(字符串[]args)引发InterruptedException{
最终认购=可观察到。从(“伦敦”、“巴黎”、“柏林”)
.flatMap(新函数1(){
@凌驾
公共可观察调用(字符串s){
返回apimager.getWeatherData;
}
})
.订阅(
新行动1(){
@凌驾
公开作废呼叫(WeatherData WeatherData){
System.out.println(Thread.currentThread().getName()+“-”+weatherData.name+”,“+weatherData.base);
}
},
新行动1(){
@凌驾
公共无效呼叫(可丢弃可丢弃){
System.out.println(Thread.currentThread().getName()+“-错误:“+throwable.getMessage());
}
},
新操作0(){
@凌驾
公开作废通知(){
System.out.println(Thread.currentThread().getName()+“-COMPLETED”);
}
}
);
//必须轮询订阅以检查其是否完成-这是唯一的方法吗?
而(!subscription.isunsubscripted()){
睡眠(100);
}
}
}
班级经理{
专用接口ApiManagerService{
@获取(“/天气”)
WeatherData getWeather(@Query(“q”)字符串位置,@Query(“units”)字符串单位);
}
private static final RestAdapter RestAdapter=new RestAdapter.Builder()
.setEndpoint(“http://api.openweathermap.org/data/2.5")
.build();
私有静态最终ApiManagerService apiManager=restAdapter.create(ApiManagerService.class);
公共静态可观测getWeatherData(最终字符串城市){
返回Observable.create(newobservable.OnSubscribe(){
@凌驾

public void call(订阅者在大多数情况下,最好不要阻止某个方法。尽量避免阻止。如果在可观察对象完成后需要执行某些操作,只需从
onCompleted
回调调用逻辑,或使用运算符

如果你真的,真的需要阻止,那么你可以使用。 这些操作符中的大多数都会阻塞,直到可观察对象完成

但是,可以通过一个简单的
System.in.read()
来阻止主方法过早退出。

如果您询问如何将异步可观察对象转换为同步可观察对象,则可以使用.toblock()然后使用.last()等待可观察对象完成。例如,即使计时器在计算线程上执行,以下操作也不会继续,直到计时器完成

试试看{
可观察
.计时器(10,时间单位为秒)
.toBlocking()
.last();//等待observable完成。丢弃最后一项。
}捕获(IllegalArgumentException ex){
//没有项目或错误。
}
除非绝对必要,否则您可能不应该使用此方法。通常,应用程序终止将由其他事件(按键、关闭菜单项单击等)控制。您的网络请求观察将异步完成,并且您将在onNext()、onCompleted()和onError()中采取操作调用以更新UI或显示错误

此外,改进的好处在于它内置了对RxJava的支持,并将在后台执行网络请求

接口ApiManagerService{
@获取(“/天气”)
可观测的getWeather(@Query(“q”)字符串位置,@Query(“units”)字符串单位);
}
这允许您将getWeatherData()方法简化为:

公共静态可观测getWeatherData(最终字符串城市){
返回apimager.getWeather(城市,“公制”);
}

为了同步等待异步观测,我编写了一个简单的函数:

public static <T> void runSynchronously(Observable<T> observable) {
    final CountDownLatch latch = new CountDownLatch(1);
    final AtomicReference<Throwable> exception = new AtomicReference<>();

    observable.subscribe(new Subscriber<T>() {
        @Override
        public void onCompleted() {
            latch.countDown();
        }

        @Override
        public void onError(Throwable e) {
            exception.set(e);
            latch.countDown();
        }

        @Override
        public void onNext(T o) {
        }
    });

    try {
        latch.await();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }

    if (exception.get() != null) {
        throw Exceptions.propagate(exception.get());
    }
}
publicstaticvoid同步运行(可观察){
最终倒计时闩锁=新倒计时闩锁(1);
最终AtomicReference异常=新的AtomicReference();
observable.subscribe(新订户(){
@凌驾
未完成的公共无效(){
public static <T> void runSynchronously(Observable<T> observable) {
    final CountDownLatch latch = new CountDownLatch(1);
    final AtomicReference<Throwable> exception = new AtomicReference<>();

    observable.subscribe(new Subscriber<T>() {
        @Override
        public void onCompleted() {
            latch.countDown();
        }

        @Override
        public void onError(Throwable e) {
            exception.set(e);
            latch.countDown();
        }

        @Override
        public void onNext(T o) {
        }
    });

    try {
        latch.await();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }

    if (exception.get() != null) {
        throw Exceptions.propagate(exception.get());
    }
}
    Observer<String> sideEffects = new Observer<String>() {
        @Override
        public void onCompleted() {
            System.out.println("onCompleted");
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("onError: " + e.getMessage());
        }

        @Override
        public void onNext(String s) {
            System.out.println("onNext: " + s);
        }
    };

    runSynchronously(
            Observable.just("London", "Paris", "Berlin")
                    .doOnEach(sideEffects)
    );