為什么可以異步?
#調用起始源碼
// 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));}