使用另一个CompletableFuture结果完成CompletableFuture [英] Complete CompletableFuture with another CompletableFuture result

查看:118
本文介绍了使用另一个CompletableFuture结果完成CompletableFuture的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在以这种方式进行异步http调用

I'm doing async http call such way

public CompletableFuture<String> doPost(String path, String json) {
        CompletableFuture<String> result = new CompletableFuture<>();
        Request request = new Request.Builder().url(this.address + path).post(RequestBody.create(json, JSON)).build();
        httpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                result.completeExceptionally(new TerminationException());
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                result.complete(response.body().string());
            }
        });
    }

但是响应可能会包含我需要重试的代码之一,而代码应该是

But it is possible that response will have one of the codes that I'll need to retry and the code should be

@Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if (!retries.contains(responce.code()) {
                    result.complete(response.body().string());
                } else {
                    // Do retry here
                }
            }

在重试中,我想递归调用doPost并将其返回值用作初始调用的结果.因此,它返回了一些可完成的未来,如何以异步方式(没有doint .get())完成完整的初始CF?

In retry I want to call doPost recursively and use it's return value as a result of initial call. So it returns some completable future, how complete initial CF with it's result in async way (without doint .get())?

谢谢.

推荐答案

您可以使用委派,例如

public CompletableFuture<String> doPost(String path, String json) {
    CompletableFuture<String> result = new CompletableFuture<>();
    doPostImpl(this.address + path, json, result, 10);
    return result;
}

private void doPostImpl(
    String url, String json, CompletableFuture<String> result, int maxRetries) {

    Request request = new Request.Builder()
        .url(url).post(RequestBody.create(json, JSON)).build();

    httpClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NotNull Call call, @NotNull IOException e) {
            result.completeExceptionally(new TerminationException());
        }

        @Override
        public void onResponse(
            @NotNull Call call, @NotNull Response response) throws IOException {

            if(maxRetries <= 0 || !retries.contains(response.code())) {
                result.complete(response.body().string());
            } else {
                doPostImpl(url, json, result, maxRetries - 1);
            }
        }
    });
}

前端方法委托给接收目标未来的方法.重试时,将在相同的将来再次调用该实现方法.因此,无需将结果从一个未来转移到另一个.

The front-end method delegates to a method receiving the target future. When retrying, the implementation method is invoked again with the same future. Therefore, there is no need to transfer results from one future to another.

从字面上看问题,您可以使用将未来的结果转移到另一个

Taking the question literally, you can transfer the result of a future to another using

future2.whenComplete((value,throwable) -> {
    if(throwable != null) future1.completeExceptionally(throwable);
    else future1.complete(value);
});

但是只要重试的次数就可以创建一个依赖链.如上所示,没有必要.

but this could create a dependency chain as long as the number of retries. As shown above, there is no need for that.

这篇关于使用另一个CompletableFuture结果完成CompletableFuture的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆