[英]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.