簡體   English   中英

用另一個 CompletableFuture 結果完成 CompletableFuture

[英]Complete CompletableFuture with another CompletableFuture result

我正在做異步 http 這樣的調用

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

但是響應可能會包含我需要重試的代碼之一,並且代碼應該是

@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 並使用它的返回值作為初始調用的結果。 所以它返回了一些完整的未來,如何以異步方式完成初始 CF(沒有 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);
            }
        }
    });
}

前端方法委托給接收目標未來的方法。 重試時,以相同的未來再次調用實現方法。 因此,沒有必要將結果從一個未來轉移到另一個未來。


從字面上理解這個問題,您可以將未來的結果轉移到另一個使用

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

但這可能會創建一個依賴鏈,只要重試次數。 如上所示,沒有必要這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM