引用 CompletableFuture 中的字段,它又可以是 CompletableFuture :java
reference to a field inside a CompletableFuture which can again be a CompletableFuture : java
我正在调用一个返回 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
没有任何意义对于那个方法。
有什么建议的方法可以让未来的参考成为另一个未来的领域。
您可以将结果提供给新的完成阶段,例如:
CompletableFuture<Output> futureOutput = makeServiceCall(input);
futureOutput.thenAcceptAsync(output -> processName(output.name));
(如果您想阻塞直到操作完成,则使用 thenAccept
)。
只需使用CompletableFuture.thenApplyAsync
来自 JavaDoc:
Returns a new CompletionStage that, when this stage completes normally, is executed using this stage's default asynchronous execution facility, with this stage's result as the argument to the supplied function.
在您的示例中(其中 T
是 processName
方法的 return 类型):
CompletableFuture<Output> future = makeServiceCall(input);
CompletableFuture<T> result = future.thenApplyAsync(o -> processName(o.name));
现在,当 makeServiceCall
CompletableFuture
完成时,会生成另一个 CompletableFuture
来包装对 processName
的异步调用 - 这会创建一个异步管道。
根据您想做什么,您可能会使用 CompletableFuture.thenAcceptAsync
来代替,例如,如果 processName
没有 return 有用的结果:
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;
});
这个管道(虽然有点做作 - 不需要获得名称 async)是完全异步的。任意点创建任务的Thread
无需阻塞;任务要么成功完成,要么调用失败处理程序。
我正在调用一个返回 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
没有任何意义对于那个方法。
有什么建议的方法可以让未来的参考成为另一个未来的领域。
您可以将结果提供给新的完成阶段,例如:
CompletableFuture<Output> futureOutput = makeServiceCall(input);
futureOutput.thenAcceptAsync(output -> processName(output.name));
(如果您想阻塞直到操作完成,则使用 thenAccept
)。
只需使用CompletableFuture.thenApplyAsync
来自 JavaDoc:
Returns a new CompletionStage that, when this stage completes normally, is executed using this stage's default asynchronous execution facility, with this stage's result as the argument to the supplied function.
在您的示例中(其中 T
是 processName
方法的 return 类型):
CompletableFuture<Output> future = makeServiceCall(input);
CompletableFuture<T> result = future.thenApplyAsync(o -> processName(o.name));
现在,当 makeServiceCall
CompletableFuture
完成时,会生成另一个 CompletableFuture
来包装对 processName
的异步调用 - 这会创建一个异步管道。
根据您想做什么,您可能会使用 CompletableFuture.thenAcceptAsync
来代替,例如,如果 processName
没有 return 有用的结果:
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;
});
这个管道(虽然有点做作 - 不需要获得名称 async)是完全异步的。任意点创建任务的Thread
无需阻塞;任务要么成功完成,要么调用失败处理程序。