我正在嘗試使用CompletableFuture來鏈接一些檔案處理程式,它應該回傳一個CompletableFuture<String>:
CompletableFuture<String> allGen = loadFile1().thenApply(params1 -> {
CompletableFuture<String> gen1 = loadFile2().thenApply(params2 -> {
return generateResultFile1(params1, params2) 。
});
CompletableFuture<String> gen2 = loadFile3().thenApply(params3 -> {
return generateResultFile2(params1, params3) 。
});
return CompletableFuture
.allOf(gen1, gen2)
.thenApply(r -> Stream.of(gen1, gen2).map(CompletableFuture::join).collect(join(",") ))。
});
我知道CompletableFuture.allOf()回傳CompletableFuture<Void>,所以我在其thenApply()中生成了一個字串...
但是為什么編譯器假設我在這里產生了一個CompletableFuture<Object>?
請問,我在這里錯過了什么?
Btw,有什么更好的方法可以像這樣連鎖方法嗎?
uj5u.com熱心網友回復:
你的主句是
CompletableFuture<String> allGen = loadFile1().thenApply(params1 -> {
...
});
所以指定的函式應該回傳一個String。但是你的代碼試圖回傳一個CompletableFuture<String>,因為Stream.of(gen1, gen2) .map(CompletableFuture::join) .collect(join(","))產生一個String而你在return CompletableFuture .allOf(gen1, gen2) .thenApply(r -> ...);
在泛型代碼中出現這種型別不匹配的情況下,編譯器的錯誤資訊往往是非常無助的。
最簡單的修復方法(變化最小)是使用thenCompose而不是thenAppy,允許該函式回傳一個CompletableFuture。
CompletableFuture<String> allGen = loadFile1().thenCompose(params1 -> {
CompletableFuture<String> gen1 = loadFile2().thenApply(params2 -> {
return generateResultFile1(params1, params2)。
});
CompletableFuture<String> gen2 = loadFile3().thenApply(params3 -> {
return generateResultFile2(params1, params3) 。
});
return CompletableFuture.allOf(gen1, gen2)
.thenApply(r -> Stream.of(gen1, gen2)
.map(CompletableFuture::join).collect(join(",")))。)
});
但是,也有機會使用簡化的語法
CompletableFuture<String> allGen = loadFile1().thenCompose(params1 -> {
CompletableFuture<String> gen1 = loadFile2()
.thenApply(params2 -> generateResultFile1(params1, params2))。
CompletableFuture<String> gen2 = loadFile3()
.thenApply(params3 -> generateResultFile2(params1, params3))。
return CompletableFuture.allOf(gen1, gen2)
.thenApply(r -> Stream.of(gen1, gen2)
.map(CompletableFuture::join).collect(join(",")))。)
});
如果代碼總是正好結合兩個結果,你可以使用更簡單的:
CompletableFuture<String> allGen = loadFile1().thenCompose(params1 ->
loadFile2().thenApply(params2 -> generateResultFile1(params1, params2))
.thenCombine()
loadFile3().thenApply(params3 -> generateResultFile2(params1, params3)) 。
(s1, s2) -> String.join(", ", s1, s2))
);
盡管嵌套不同,loadFile2().thenApply(...)和loadFile3().thenApply(...)仍然是兩個獨立的操作,只有最后的(s1, s2) -> String.join(", ", s1, s2) 依賴于兩者。
如果你想讓這一點更明顯,請保留區域變數
CompletableFuture<String> allGen = loadFile1().thenCompose(params1 -> {
CompletableFuture<String> gen1
= loadFile2().thenApply(params2 -> generateResultFile1(params1, params2))。
CompletableFuture<String> gen2
= loadFile3().thenApply(params3 -> generateResultFile2(params1, params3) )。
return gen1.thenCombine(gen2, (s1, s2) -> s1 ", " s2)。
});
如上例所示,你也可以在這里用s1 "," s2代替String.join(",", s1, s2)。后者的效率會稍高一些,但由于它不太可能主導整體性能,所以這只是一個品味問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/318639.html
標籤:
