更具体地说,这两段代码有什么区别,一个返回void
,另一个返回CompletionStage<Void>
?
void
或CompletionStage<Void>
中的一个相对于另一个有什么优势?x
中的变量thenCompose
。有没有更好的书写方式?boolean
中返回doValidation
并检查true
函数中的performTask
是否是更好的做法?代码示例1:
public CompletionStage<Response> performTask(Request request) throws MyException {
doValidation(request);
return service.performTask(request).thenCompose(serviceResponse -> CompletableFuture.completedFuture(buildMyResponse(serviceResponse)));
}
private void doValidation(Request request) throws MyException {
CompletableFuture.runAsync(() -> {
// Validate
if (*someCondition*) {
throw new MyException(.....);
}
});
}
代码示例2:
public CompletionStage<Response> performTask(Request request) throws MyException {
return doValidation(request).thenCompose(x -> {
return service.performTask(request).thenCompose(serviceResponse -> CompletableFuture.completedFuture(buildMyResponse(serviceResponse)));
});
}
private CompletionStage<Void> doValidation(Request request) throws MyException {
return CompletableFuture.runAsync(() -> {
// Validate
if (*someCondition*) {
throw new MyException(.....);
}
});
}
答案 0 :(得分:2)
我正在解决您的第一个问题
What advantages of using one of void or CompletionStage<Void> over the other?
要了解差异,您应该尝试记录流程。它将帮助您确定两者的工作方式有何不同。
这是与您遵循的方法类似的示例。我提出了自己的示例,因为我不知道您的代码。
public class Test {
public static void main(String[] args) {
tryWithVoid();
// tryWithCompletionStageVoid();
}
public static void tryWithVoid() {
System.out.println("Started");
validate(null);
System.out.println("Exit");
}
public static void tryWithCompletionStageVoid() {
System.out.println("Started");
validateCS(null).thenRun(() -> System.out.println("Validation complete"));
System.out.println("Exit");
}
public static CompletionStage<Void> validateCS(String val) {
return CompletableFuture.runAsync(() -> {
if (val == null) {
System.out.println("Validation failed! value is null");
}
});
}
public static void validate(String val) {
CompletableFuture.runAsync(() -> {
if (val == null) {
System.out.println("Validation failed! value is null");
}
});
}
}
如果运行tryWithVoid()
,您将看到输出为:
Started
Exit
Validation failed! value is null
运行tryWithCompletionStageVoid()
时,它将是:
Started
Validation failed! value is null
Validation complete
Exit
在第一种方法tryWithVoid()
中,它不等待操作完成。因此,调用后的代码可能无法获得操作结果。
但是,在第二种方法tryWithCompletionStageVoid()
中,它在运行下一阶段之前等待该阶段完成。
如果您在各个阶段之间没有依赖性,则可以使用void
答案 1 :(得分:2)
区别在于,返回void
后,您将无法执行链接到CompletableFuture
的任何操作。
当您返回CompletableFuture<Void>
时,您可以将其他内容链接到它。例如,调用thenRun()
,thenRunAsync()
或仅调用join()
来等待它完成(如果需要)。
因此,这取决于调用方是否关心CompletableFuture
的状态,并希望应用附加的逻辑。
在您的情况下,在示例1中,doValidation()
在单独的线程上运行,而发生的任何事情实际上都是无关紧要的。 service.performTask()
的发生与它无关,甚至可以在doValidation()
之前开始和/或结束。
在示例2中,doValidation()
必须成功完成performTask()
才能实际完成。因此,似乎该版本实际上是正确的版本。请记住,正在运行CompletionStage<Response> performTask()
的 main 线程将完成并在设置管道后立即返回,实际的performValidation()可能仍在运行(甚至可能尚未启动)。 。
通过以下方式可以简化通话:
service.performTask(request).thenApply(this::buildMyResponse);
您不必再次将其包装在CompletableFuture
中,而只需用thenCompose()
重新包装。