Java 避免复制可完成未来的状态
我试图返回一个Java 避免复制可完成未来的状态,java,completable-future,Java,Completable Future,我试图返回一个CompletableFuture,它将从Amazon返回一个响应。我的代码首先检查响应是否在本地缓存。如果是,则返回响应,否则调用Amazon。[注意:真实版本还将缓存从Amazon收到的响应,但我没有包括这些,因为代码已经相当复杂了。] 有没有办法更改我的callAmazon方法的实现(或者重新组织代码),这样我就不必“手动”将响应状态从amazonApi复制到finalResponse 我不想直接返回cacheCheck,因为我不希望调用方能够complete()it pub
CompletableFuture
,它将从Amazon返回一个响应。我的代码首先检查响应是否在本地缓存。如果是,则返回响应,否则调用Amazon。[注意:真实版本还将缓存从Amazon收到的响应,但我没有包括这些,因为代码已经相当复杂了。]
有没有办法更改我的callAmazon
方法的实现(或者重新组织代码),这样我就不必“手动”将响应状态从amazonApi
复制到finalResponse
我不想直接返回cacheCheck
,因为我不希望调用方能够complete()
it
public CompletableFuture<Response> fetchProductList() {
CompletableFuture<Response> finalResponse = new CompletableFuture<>();
CompletableFuture<Response> cacheCheck = //...
// First, see if we have a cached copy
cacheCheck.whenComplete((response, throwable) -> {
if (throwable == null) {
// Cache hit. Return the cached response
finalResponse.complete(response);
} else {
// Cache miss. Call Amazon
callAmazon(finalResponse);
}
});
return finalResponse;
}
private void callAmazon(CompletableFuture<Response> finalResponse) {
CompletableFuture<Response> amazonApi = //...
amazonApi.whenComplete((response, throwable) -> {
// Copy the state to the `finalResponse`
if (throwable == null) {
finalResponse.complete(response);
} else {
finalResponse.completeExceptionally(throwable);
}
});
}
public CompletableFuture fetchProductList(){
CompletableFuture finalResponse=新的CompletableFuture();
CompletableFuture cacheCheck=/。。。
//首先,查看是否有缓存副本
缓存检查。完成时((响应,可丢弃)->{
if(throwable==null){
//缓存命中。返回缓存响应
最终响应完成(响应);
}否则{
//缓存小姐,打电话给亚马逊
呼叫亚马逊(最终响应);
}
});
返回最终响应;
}
私有无效调用Amazon(可完成的未来最终响应){
CompletableFuture amazonApi=/。。。
amazonApi.完成时((响应,可丢弃)->{
//将状态复制到“finalResponse”`
if(throwable==null){
最终响应完成(响应);
}否则{
最终响应完全例外(可丢弃);
}
});
}
使您的需求如此复杂的是cacheCheck
可能引发异常
在您的情况下,我要做的是重构缓存,如果在缓存中找不到值,则传递null
,如果值在缓存中,则传递实际的响应
此外,我会修改callAmazon
,直接返回CompletableFuture
:
private CompletableFuture<Response> callAmazon() {
CompletableFuture<Response> amazonApi = //...
return amazonApi;
}
private CompletableFuture callAmazon(){
CompletableFuture amazonApi=/。。。
返回amazonApi;
}
通过这种方式,您可以使用:
final CompletableFuture cacheCheck=/。。。
最终CompletableFuture amazonResponse=callAmazon();
最终可完成的未来最终结果=
cachedResponse.thenCompose(cacheResult->{
返回cacheResult==null?amazonResponse:CompletableFuture.completedFuture(cacheResult);
});
如果确实需要从缓存中抛出异常,可以使用将异常转换为空值,然后使用合成来决定是否使用缓存值,或者调用Amazon:
final CompletableFuture<Response> finalResult = cachedResponse.exceptionally(e -> {
return null;
}).thenCompose(cacheResult -> {
return cacheResult == null ? amazonResponse : CompletableFuture.completedFuture(cacheResult);
});
final completable future finalResult=cachedResponse.异常(e->{
返回null;
}).然后编写(缓存结果->{
返回cacheResult==null?amazonResponse:CompletableFuture.completedFuture(cacheResult);
});
退房。然后撰写:嗨,亚历杭德罗,我试着想在这种情况下如何使用然后撰写
,但我不知道它是如何工作的。我想你不可能写出一些代码,可以吗?为什么你要为调用方调用complete()
而烦恼呢?您是否要在几个调用之间共享此CompletableFuture
?无论如何,您可以通过返回a来轻松隐藏该方法(但是toCompletableFuture()
将取消隐藏它)
创建一个新的CompletableFuture
实例,我可以返回该实例。我不希望调用者完成它的原因是我想缓存来自Amazon的真实结果,而不是调用者决定放在那里的结果。
final CompletableFuture<Response> finalResult = cachedResponse.exceptionally(e -> {
return null;
}).thenCompose(cacheResult -> {
return cacheResult == null ? amazonResponse : CompletableFuture.completedFuture(cacheResult);
});