并行调用API时收集失败请求的ProductId方案咨询
解决方案
要实现需求,核心是把请求的ProductId和对应的API响应/执行状态绑定,因为返回的ProductResponse不包含原请求ID。同时要覆盖两种失败场景:API返回isSuccessAPI=false,以及API调用抛出异常(比如网络错误、超时)。
修改后的完整代码
import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; public class ProductService { private ProductAPI productAPI; // 假设这是已注入的API实例 public void runAllAPIs() { List<Integer> productIds = Arrays.asList(2, 5, 7); // 把ProductId和对应的异步任务绑定,用SimpleEntry保存键值对 List<Map.Entry<Integer, CompletableFuture<ProductResponse>>> idFuturePairs = productIds.stream() .map(productId -> new AbstractMap.SimpleEntry<>( productId, createProduct(productId) )) .collect(Collectors.toList()); List<Integer> failedProductIds = new ArrayList<>(); for (Map.Entry<Integer, CompletableFuture<ProductResponse>> pair : idFuturePairs) { Integer productId = pair.getKey(); CompletableFuture<ProductResponse> future = pair.getValue(); try { ProductResponse response = future.get(); // 检查API返回的成功标记 if (!response.isSuccessAPI()) { failedProductIds.add(productId); } } catch (InterruptedException | ExecutionException e) { // 处理API调用抛出的异常(比如网络失败、超时) failedProductIds.add(productId); // 可按需添加异常日志:e.printStackTrace(); } } // 输出失败的ProductId列表 System.out.println("请求失败的ProductId: " + failedProductIds); } private CompletableFuture<ProductResponse> createProduct(int productId) { return CompletableFuture.supplyAsync(() -> productAPI.createProduct(productId)) // 可选优化:统一将异常转换为标记失败的响应,后续无需捕获异常 .exceptionally(e -> { ProductResponse errorResponse = new ProductResponse(); errorResponse.setSuccessAPI(false); errorResponse.setTransactionId(-1); // 用特殊值标记异常场景 return errorResponse; }); } // 假设的ProductAPI接口 interface ProductAPI { ProductResponse createProduct(int productId); } @Data public static class ProductResponse { private boolean isSuccessAPI; private int transactionId; } }
关键说明
- 绑定请求ID与任务:通过
AbstractMap.SimpleEntry将每个ProductId和对应的CompletableFuture关联,确保后续能追踪到每个请求的来源ID。 - 覆盖两类失败场景:
- 业务失败:API返回
isSuccessAPI=false时,直接收集对应ProductId; - 执行异常:API调用抛出网络错误、超时等异常时,通过
try-catch捕获并标记该ID为失败。
- 业务失败:API返回
- 保证并行不中断:逐个处理异步任务,即使某一个任务执行失败,循环仍会继续处理剩余任务,满足“单个失败不影响其他执行”的要求。
- 可选简化方案:在
createProduct中用exceptionally将异常转换为标记失败的ProductResponse,后续可以统一通过响应的isSuccessAPI判断,无需额外捕获异常,代码更整洁。
内容的提问来源于stack exchange,提问作者mattsmith5
相关产品推荐
相关产品推荐

