我完全支持批准的答案,但是我我也在为这些类型的问题而创建的东西中折腾,这些问题当时派上用场您开始在异步操作链中添加条件逻辑。我最近发酵成一个简单的图书馆(jasync-driver)。
下面是你如何连接你的例子。正如你所看到的,每个任务都不知道下面的任务。与批准的答案相反,任务的链接是通过简单的同步(...查看)方法体而不是列表完成的。
public void doChainedLogic() {
final AsyncTask<Void, Void> doSomething = new AsyncTask<Void, Void>() {
@Override
public void run(Void arg, final ResultHandler<Void> resultHandler) {
get("/something", new Callback() {
public void onComplete(String data) {
updateUi(something, data);
resultHandler.reportComplete();
}
});
}
};
final AsyncTask<Void, Void> doSomethingElse = new AsyncTask<Void, Void>() {
@Override
public void run(Void arg, final ResultHandler<Void> resultHandler) {
get("/something/else", new Callback() {
public void onComplete(String data) {
updateUi(somethingElse, data);
resultHandler.reportComplete();
}
});
}
};
final AsyncTask<Void, Void> doYetAnotherThing = new AsyncTask<Void, Void>() {
@Override
public void run(Void arg, final ResultHandler<Void> resultHandler) {
get("/yet/another/thing", new Callback() {
public void onComplete(String data) {
updateUi(yetAnotherThing, data);
resultHandler.reportComplete();
}
});
}
};
// This looks synchronous, but behind the scenes JasyncDriver is
// re-executing the body and skipping items already executed.
final JasyncDriver driver = new JasyncDriver();
driver.execute(new DriverBody() {
public void run() {
driver.execute(doSomething);
driver.execute(doSomethingElse);
driver.execute(doYetAnotherThing);
}
});
}
现在,这里是一个调整的例子包括取决于异步结果一些有条件的逻辑:
final AsyncTask<Void, String> checkSomething = new AsyncTask<Void, String>() {
@Override
public void run(Void arg, final ResultHandler<String> resultHandler) {
get("/check/something", new Callback() {
public void onComplete(String data) {
resultHandler.reportComplete(data);
}
});
}
};
final JasyncDriver driver = new JasyncDriver();
driver.execute(new DriverBody() {
public void run() {
driver.execute(doSomething);
if ("foobar".equals(driver.execute(checkSomething))) {
driver.execute(doSomethingElse);
}
driver.execute(doYetAnotherThing);
}
});
正如你所看到的,异步的条件逻辑是写if语句标准的那样简单。
我过分简化了一下问题陈述:在我的情况下,异步操作都是对REST API的HTTP调用。每个电话都是对不同URL的请求。话虽如此,你对我的问题的阅读非常接近!你提出的解决方案很有趣 - 我必须尝试一下,看看它是如何工作的。我还必须寻找一种方法来使其真正实现异步和非阻塞。 – curioustechizen 2014-10-06 12:06:11
@curioustechizen关于*“真正的异步和非阻塞”*:我认为调用/任务必须被阻塞,这意味着一个应该在另一个之后执行(否则你在问题中勾画的“链接”不会使感)。因此,如果这个*“非阻塞”*仅指全部调用序列:通过将每个任务传递给'ExecutorService#submit'方法,您可以单独将任务提交给'ExecutorService',而不是使用'invokeAll' ,在'for'循环中。然后提交任务的线程将继续,任务将在后台处理 – Marco13 2014-10-06 12:25:29