thenAccept
用途: 适用于你需要在异步任务完成后执行一些操作,比如将结果存入数据库、发送到另一个服务、更新状态等,但不需要返回任何新的计算结果。
thenApply
用途: 适用于你需要对异步任务的结果进行转换或处理,然后将处理结果作为下一个操作的输入。可以链式调用多个 thenApply
方法来实现多步操作
区别总结
-
返回类型:
thenAccept
返回CompletableFuture<Void>
,表示处理结果后不返回新的结果;而thenApply
返回CompletableFuture<U>
,其中U
是计算函数的返回类型,表示处理结果后返回新的计算结果。 -
用途不同:
thenAccept
适合于处理结果但不需要返回任何新的计算结果的场景;而thenApply
则适合于处理结果,并且需要返回一个新的计算结果供后续操作使用
thenApply 返回批量查询结果
样例
public List<GaoDeDistanceResDTO> queryGaoDeDistanceBatch(List<GaoDeDistanceReqDTO> reqDTOs) {
if (CollectionUtils.isEmpty(reqDTOs)) {
log.info("查询高德距离 参数为空");
return Collections.emptyList();
}
try {
org.springframework.util.StopWatch stopWatch = new org.springframework.util.StopWatch("查询高德距离");
stopWatch.start("查询高德距离开始");
List<GaoDeDistanceResDTO> resDTOS = new ArrayList<>();
int count = 0;
List<CompletableFuture<Pair<GaoDeDistanceReqDTO, JSONObject>>> queryFutures = new ArrayList<>();
for (GaoDeDistanceReqDTO reqDTO : reqDTOs) {
count++;
if (count >= qpsLimit) {
try {
count = 0;
Thread.sleep(1000L);
} catch (InterruptedException e) {
log.error("查询高德距离 异常 线程中断。请求参数: {}", JSON.toJSONString(reqDTO), e);
}
}
Map<String, String> mapInfo = buildParam(reqDTO.getOrigin(), reqDTO.getDestination());
CompletableFuture<Pair<GaoDeDistanceReqDTO, JSONObject>> future = CompletableFuture.supplyAsync(() -> {
JSONObject result = restTemplate.getForObject(drivingUrlGaoDe, JSONObject.class, mapInfo);
Map map = JSON.parseObject(result.toString(), Map.class);
String status = (String) map.get("status");
if (Objects.isNull(result) || Objects.isNull(map) || Boolean.FALSE.equals("1".equals(status))) {
log.error("查询高德距离 失败。请求参数: {},响应参数: {}", JSON.toJSONString(mapInfo), result);
return null;
}
Pair<GaoDeDistanceReqDTO, JSONObject> pair = new Pair<>(reqDTO, result);
return pair;
}, threadPoolTaskExecutor);
queryFutures.add(future);
}
CompletableFuture<Void> allQueriesFuture = CompletableFuture.allOf(queryFutures.toArray(new CompletableFuture[0]));
CompletableFuture<List<Pair<GaoDeDistanceReqDTO, JSONObject>>> batchResultFuture = allQueriesFuture.thenApply(v -> queryFutures.stream().map(CompletableFuture::join) // 获取每个 CompletableFuture 的结果
.collect(Collectors.toList()));
List<Pair<GaoDeDistanceReqDTO, JSONObject>> batchResults = batchResultFuture.get();
batchResults.forEach(x -> {
GaoDeDistanceReqDTO reqDTO = x.getLeft();
String distance = getDistance(x.getRight());
GaoDeDistanceResDTO resDTO = new GaoDeDistanceResDTO(reqDTO.getKey(), reqDTO.getOrigin(), reqDTO.getDestination(), distance);
resDTOS.add(resDTO);
});
stopWatch.stop();
stopWatch.prettyPrint();
log.info("查询高德距离 耗时统计 数据量: {},总耗时: {}", reqDTOs.size(), stopWatch.prettyPrint());
return resDTOS;
} catch (Exception e) {
log.error("查询高德距离,异常 入参: {}", JSON.toJSONString(reqDTOs), e);
}
return Collections.emptyList();
}