gpt4 book ai didi

java - 链接一系列异步调用

转载 作者:搜寻专家 更新时间:2023-10-30 21:30:30 24 4
gpt4 key购买 nike

我有一系列的异步操作

private void doSomething(){
get("/something", new Callback(){
void onComplete(String data){
updateUi(something, data);
doSomethingElse();
}
});
}

private void doSomethingElse(){
get("/something/else", new Callback(){
void onComplete(String data){
updateUi(somethingElse, data);
doYetAnotherThing();
}
});
}

private void doYetAnotherThing(){
get("/yet/another/thing", new Callback(){
void onComplete(String data){
updateUi(yetAnotherThing, data);
allDone();
}
});
}

这有几个问题:

  1. 不能在别处重复使用任何回调,因为每个回调都与“下一步”有内在联系
  2. 重新排序操作或插入另一个操作是不直观的,需要到处跳转。

我研究了以下选项来缓解这种情况:

  1. ExecuterService#invokeAll - 我看不出如何在不阻塞的情况下使用这个解决方案。
  2. RxJava - 如果可以的话,我宁愿在我的应用程序中避免这种范式转变!
  3. Guava 的 ListenableFutures 及其 transform 方法。我在互联网周围的几个地方看到了这一点,老实说,我看不出这将如何解决我的问题。

因此,问题是:在 Java 中链接一系列异步调用的好的模式是什么?正在寻找适用于 Java 7 的解决方案,因为我的 Android 应用程序需要它。

最佳答案

关于您遇到此问题的实际意图和用例,肯定涉及一些猜测。此外,还不完全清楚 somethingsomethingElseyetAnotherThing 是什么(它们从哪里来,应该去哪里)。

但是,根据您提供的信息,作为对 answer by slartidan 的补充(或者说是扩展或概括) : 你在那里勾勒的这些虚拟电话之间的区别似乎是

  • 传递给 get 方法的 String 参数
  • 被调用的Callback
  • 接下来执行哪个方法

您可以分解出这些部分:String 参数和 Callback 可以作为参数传递给创建 Callable 的通用方法.调用顺序可以简单地通过将这些 Callable 对象以适当的顺序放入列表中来定义,并使用 单线程 执行器服务执行它们。 p>

正如您在本例的 main 方法中看到的,调用顺序可以很容易地配置:

import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class ChainedAsyncTest {

public static void main(String[] args) throws InterruptedException {
ChainedAsyncTest t = new ChainedAsyncTest();
ExecutorService e = Executors.newFixedThreadPool(1);
e.invokeAll(Arrays.asList(
t.call("/something", t.somethingCallback),
t.call("/something/else", t.somethingElseCallback),
t.call("/yet/another/thing", t.yetAnotherThingCallback),
t.allDone()));
}

private Callback somethingCallback = new Callback() {
@Override
public void onComplete(String data) {
updateUi("something", data);
}
};

private Callback somethingElseCallback = new Callback() {
@Override
public void onComplete(String data) {
updateUi("somethingElse", data);
}
};

private Callback yetAnotherThingCallback = new Callback() {
@Override
public void onComplete(String data) {
updateUi("yetAnotherThing", data);
}
};

private Callable<Void> call(
final String key, final Callback callback) {
return new Callable<Void>() {
@Override
public Void call() {
get(key, callback);
return null;
}
};
}

private Callable<Void> allDone() {
return new Callable<Void>() {
@Override
public Void call() {
System.out.println("allDone");
return null;
}
};
}



interface Callback
{
void onComplete(String data);
}
private void get(String string, Callback callback) {
System.out.println("Get "+string);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
callback.onComplete("result of "+string);
}
private void updateUi(String string, String data) {
System.out.println("UpdateUI of "+string+" with "+data);
}

}

(该示例使用 invokeAll,它会阻塞,直到所有任务都已执行。这可以通过不同的方式解决,以在调用站点实现真正的非阻塞。主要思想是创建一个列表任务,它们都是由相同的方法调用创建的)

关于java - 链接一系列异步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26059300/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com