使用另一个 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 并使用它的 return 值作为初始调用的结果。
所以它 return 是一些可完成的未来,它如何以异步方式完成初始 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);
});
但这可能会创建一个与重试次数一样长的依赖链。如上图,不需要那个。
我正在以这种方式进行异步 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 并使用它的 return 值作为初始调用的结果。 所以它 return 是一些可完成的未来,它如何以异步方式完成初始 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);
});
但这可能会创建一个与重试次数一样长的依赖链。如上图,不需要那个。