我有一个异步方法
asyncClass.getChild("test", listChild -> {
if (listChild.isOk()) {
List<String> list = listChild.isSuccess().getData()
}
return null;
});
如何将这个异步调用包装在CompletableFuture中?
final CompletableFuture<List<String>> future = new CompletableFuture<>();
asyncClass.getChild("test", listChild -> {
if (listChild.isOk()) {
future.complete(listChild.isSuccess().getData());
}
return null;
});
return future;
一切正常,但我希望一切都在单独的线程调用中工作
interface AsyncFS {
fun getChild(path: String, onResult: (Result<List<String>>) -> Unit)
}
答案 0 :(得分:3)
似乎asyncClass.getChild
是异步执行的(因为它需要回调)。如果是这样,那么您当前的实现就足够了(下面的更正除外)。
asyncClass.getChild("test", listChild -> {
if (listChild.isOk()) {
future.complete(listChild.isSuccess().getData());
} else {
future.complete(null); //you need to do this
//or future.completeExceptionally(exception) if this is a failure
}
});
如果您希望getChild
在单独的线程中运行,那么我强烈建议您重新设计该方法,使其返回List<String>
而不是进行回调。这种设计使其笨拙地异步运行getChild
。
interface AsyncFS {
fun getChild(path: String): List<String> //don't trust my syntax
}
然后以这种方式异步运行它:
CompletableFuture<List<String>> future =
CompletableFuture.supplyAsync(() -> asyncClass.getChild("test"));
return future;
答案 1 :(得分:0)
将Runnable或Supplier作为CompletableFuture.runAsync()
或supplyAsync()
的参数
return CompletableFuture.runAsync(() -> {
doSomething();
}, optionalExecutor);
答案 2 :(得分:0)
更改您的getChild()
方法以返回CompletableFuture<ListChild>
而不是将回调作为参数。
没有实际的代码,我无法确切地说出必须执行的操作,但是基本上代码看起来像
CompletableFuture<ListChild> result = new CompletableFuture<>();
processAsynchronously(path, result);
return result;
其中processAsynchronously()
执行异步计算,并在某些时候调用result.complete(listChild)
。
然后,呼叫者将能够轻松地像
那样链接电话CompletableFuture<List<String>> result = asyncClass.getChild("test")
.thenAcceptAsync(listChild -> {
if (listChild.isOk()) {
return listChild.isSuccess().getData()
}
return null;
}, executor);
或其他任何使用他想要的执行器的处理。
如您所见,这比强制执行特定类型的回调要灵活得多。