[英]Callback with CompletableFuture
我正在尝试使用一些字符串创建一个非常简单的回调。 IDE的代码含义是抱怨异常的未经检查的调用。 谁能解决这个问题? 最后的想法是包装一个网络调用,以便返回预期的结果,我可以根据需要添加其他功能。
import java.util.concurrent.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class FuturesTest {
public static void main(String[] args) throws Exception {
new FuturesTest().go();
}
private void go() throws ExecutionException, InterruptedException {
CompletableFuture.supplyAsync(new MakesANetworkCall())
.whenComplete(new BiConsumer<String, String>() {
@Override
public void accept(String result, String s) {
System.out.println(result.toString());
}
})
.exceptionally(new Function<Exception, Exception>() {
@Override
public Exception apply(Exception e) {
e.printStackTrace();
return e;
}
}
).thenApplyAsync(new Function<String, String>() {
@Override
public String apply(String o) {
System.out.println("Last action of all!");
return null;
}
});
System.out.println("Main thread will sleep");
Thread.sleep(2500);
System.out.println("Program over");
}
class MakesANetworkCall implements Supplier {
@Override
public String get() {
try {
System.out.println("Ground control to Major Tom");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// int i = 2/0;
return new String("Major Tom reporting!");
}
}
}
首先,您的类MakesANetworkCall
实现原始类型Supplier
而不是Supplier<String>
。 这将有效地禁用类型检查并隐藏您所犯的所有错误,因此这不是您应该担心的单个警告,因为这不是代码中唯一的错误:
该BiConsumer
传递给whenComplete
应该能够消耗Throwable
作为第二个参数。
传递给exceptionally
的Function
应该消耗Throwable
并返回替代结果。
此外,您正在使用表达式new CompletableFuture<String>()
作为目标来调用static
方法,并且具有过时的字符串创建表达式作为new String("Major Tom reporting!")
,其中简单常量"Major Tom reporting!"
会做。 通常,您似乎总是尝试使用一种不合适的方法,例如,一种旨在消耗您不使用的东西的方法,或者一种用于提供您没有的东西的价值的方法。 考虑一下:
CompletableFuture.supplyAsync(new MakesANetworkCall())
.thenAccept(result -> System.out.println(result))
.exceptionally(e -> { e.printStackTrace(); return null;})
.thenRun(()->System.out.println("Last action of all!"));
这似乎是您的意图。 如果确保MakesANetworkCall
正确实现了Supplier<String>
,则应在编译时没有任何警告。
您的核心问题是class MakesANetworkCall implements Supplier {
。 这使用的是原始类型,因此隐藏了更多问题。 修复该问题,使class MakesANetworkCall implements Supplier<String> {
并解决所有随之而来的问题,您将获得:
CompletableFuture.supplyAsync(new MakesANetworkCall())
// Not <String, String>
.whenComplete(new BiConsumer<String, Throwable>() {
@Override
public void accept(String result, Throwable t) {
System.out.println(result);
}
})
// Not <Exception,Exception>
.exceptionally(new Function<Throwable, String>() {
@Override
public String apply(Throwable t) {
t.printStackTrace();
// Must return a Streing
return t.getMessage();
}
}
).thenApplyAsync(new Function<String, String>() {
@Override
public String apply(String o) {
System.out.println("Last action of all!");
return null;
}
});
像这样声明CompletableFuture.exceptionally
:
public CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn);
您正在传递给它一个Function<Exception, Exception>
,而应该传递给它一个Function<Throwable, String>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.