为什么可以异步?
#调用起始源码
// 3. 发送异步请求并处理响应
CompletableFuture future = client.sendAsync(
request,
HttpResponse.BodyHandlers.ofString() // 响应体转为字符串
).thenApply(response -> {
// 状态码检查(非200系列抛出异常)
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new RuntimeException("HTTP错误: " + response.statusCode());
}
return response;
}).thenApply(HttpResponse::body) // 提取响应体3
.thenAccept(body -> {
// 4. 打印响应结果(截取前100字符示例)
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("\n▼ 响应内容 (前100字符):\n"
- body.substring(0, Math.min(100, body.length())) + "...");
}).exceptionally(e -> {
// 5. 异常处理(提取根本原因)
Throwable root = e;
while (root.getCause() != null) root = root.getCause();
System.err.println("❌ 请求失败: " + root.getMessage());
return null;
});
#client.sendAsync
public CompletableFuture<T> whenComplete(
BiConsumer<? super T, ? super Throwable> action) {
return uniWhenCompleteStage(null, action);
}

@Override
public CompletableFuture<HttpResponse>
sendAsync(HttpRequest userRequest, BodyHandler responseHandler)
{
return sendAsync(userRequest, responseHandler, null);
}
@Override
public <T> CompletableFuture<HttpResponse<T>>
sendAsync(HttpRequest userRequest,
BodyHandler<T> responseHandler,
PushPromiseHandler<T> pushPromiseHandler) {
return sendAsync(userRequest, responseHandler, pushPromiseHandler, delegatingExecutor.delegate);
}
#关键在这里
@SuppressWarnings("removal")
private CompletableFuture<HttpResponse>
sendAsync(HttpRequest userRequest,
BodyHandler responseHandler,
PushPromiseHandler pushPromiseHandler,
Executor exchangeExecutor) {
Objects.requireNonNull(userRequest);
Objects.requireNonNull(responseHandler);
MultiExchange<T> mex = new MultiExchange<>(userRequest,
requestImpl,
this,
responseHandler,
pushPromiseHandler,
acc);
CompletableFuture<HttpResponse<T>> res =
mex.responseAsync(executor).whenComplete((b,t) -> unreference());
if (DEBUGELAPSED) {
res = res.whenComplete(
(b,t) -> debugCompleted("ClientImpl (async)", start, userRequest));
}
