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