CompletableFuture包装器

时间:2018-08-17 12:34:04

标签: java multithreading asynchronous completable-future

我有一个异步方法

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)
}

3 个答案:

答案 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);

或其他任何使用他想要的执行器的处理。

如您所见,这比强制执行特定类型的回调要灵活得多。