Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 避免复制可完成未来的状态_Java_Completable Future - Fatal编程技术网

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);
    });