我正在调用一个返回CompletableFuture的服务。
输出结构如下。
Class Output {
public String name;
public Integer age;
}
我想打电话给服务,并希望继续我的执行,直到名字出现。
类似的东西,
CompletableFuture<Output> futureOutput = makeServiceCall(input);
String name = futureOutput.get().name;
processName(name); // which will do some costly operations and make use of the name at the end.
在上面的方法中,我需要等到我的futureOutput
准备就绪,即使我以后只需要它。
我寻找类似下面的方法。
CompletableFuture<Output> futureOutput = makeServiceCall(input);
CompletableFuture<String> futureName = futureOutput.get().name; // This is wrong, but can we create a reference in a similar way?
processName(futureName); // which will do some costly operations and make use of the name at the end.
我可以将processName
的签名从String
更改为CompletableFuture<String>
而不是CompletableFuture<Output>
,因为Output
对此没有任何意义方法。
有什么建议的方法来获得未来的参考,这是另一个未来的领域。
答案 0 :(得分:6)
CompletableFuture.thenApplyAsync
来自JavaDoc:
返回一个新的CompletionStage,当这个阶段正常完成时,使用这个阶段的默认异步执行工具执行,该阶段的结果作为所提供函数的参数。
在您的示例中(T
是processName
方法的返回类型):
CompletableFuture<Output> future = makeServiceCall(input);
CompletableFuture<T> result = future.thenApplyAsync(o -> processName(o.name));
现在,当makeServiceCall
CompletableFuture
完成时,会生成另一个CompletableFuture
以将异步调用包装到processName
- 这会创建一个异步管道。
根据您的目的,您可以改为使用CompletableFuture.thenAcceptAsync
,例如,如果processName
没有返回有用的结果:
CompletableFuture<Output> future = makeServiceCall(input);
CompletableFuture<Void> result = future.thenAcceptAsync(o -> processName(o.name));
如果此处理未完成,您可能还需要进行错误处理,这可以通过CompletableFuture.exceptionally
来完成。如果处理管道以Exception
终止,则会添加一个回调函数。
通过完整的示例,您可以:
makeServiceCall(input)
.thenApplyAsync(Output::getName)
.thenAcceptAsync(this::processName)
.exceptionally(e -> {
//log the error
System.out.printf("Oops - %s%n", e);
//return some useful default value
return ProcessingResult.SUCCESSFUL;
});
这个管道(虽然有点做作 - 没有必要得到名称异步)是完全异步的。无需阻止任何点创建任务的Thread
;任务将成功完成或将调用失败处理程序。
答案 1 :(得分:0)
您可以将结果提供给新的完成阶段,例如:
CompletableFuture<Output> futureOutput = makeServiceCall(input);
futureOutput.thenAcceptAsync(output -> processName(output.name));
(如果要在操作完成之前阻止,请使用thenAccept
。