You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移除Java代码中的CompletableFuture将异步转为同步并处理响应错误

关于CompletableFuture异步逻辑改同步的改造方案

一、不能直接删除futures.add(CompletableFuture.supplyAsync(()部分

核心原因有两点:

  • 原方法依赖List<CompletableFuture<String>>类型的入参收集异步任务结果,改成同步后该入参完全无用,方法签名需要先调整
  • 原逻辑里supplyAsync包裹的异步执行逻辑、handle绑定的结果/异常处理逻辑是绑定在一起的,直接删除会导致业务逻辑断裂

二、具体改造步骤

第一步:修改方法签名

删除无用的futures入参,根据业务需要选择返回处理后的结果集合,或者保持无返回:

// 示例方法签名,可根据实际需求调整返回值
private List<String> getClockRequestList(String createdBy, String capacityType, ResourceHierarchy rA, int[] clock_ids, Boolean checkIfCreatingClock, String url)
            throws JsonProcessingException {
    List<String> resultList = new ArrayList<>();
    // 改造后的业务逻辑放在这里
    return resultList;
}

第二步:异步逻辑转同步执行

把supplyAsync包裹的HTTP调用逻辑直接拿出顺序执行,handle内的结果处理逻辑直接跟在HTTP调用后面即可,不需要再包CompletableFuture:

for (int clockid : clock_ids) {
    String clockRequest = requestMapperImpl.getClockRequest(createdBy, capacityType, String.valueOf(clockid),
            rA, checkIfCreatingClock);
    String response = null;
    Throwable error = null;
    // 同步执行HTTP请求,移除异步包裹
    try {
        response = genericRestClientImp.httpPostData(clockRequest, url);
        logger.info("Response from EAM is: {}",response);
    } catch (IOException e) {
        logger.error(e);
        error = e;
    }
    // 原handle内的结果处理逻辑完全复用
    String handleResult;
    if (response != null && error == null) {
        if (checkIfCreatingClock) {
            if (response.contains(AppConstant.FAILURE_MSG)) {
                logger.info(responseMapperImpl.responseMessageClock(AppConstant.FAILURE, response, rA, clockid));
                handleResult = responseMapperImpl.responseMessageClock(AppConstant.FAILURE, response, rA, clockid);
            } else if (response.contains(AppConstant.STATUS_404)) {
                logger.info(responseMapperImpl.responseMessageClock(AppConstant.STATUS_404, response, rA, clockid));
                handleResult = responseMapperImpl.responseMessageClock(AppConstant.STATUS_404, response, rA, clockid);
            } else if (response.contains(AppConstant.SUCCESS_MSG)) {
                logger.info(responseMapperImpl.responseMessageClock(AppConstant.SUCCESS, response, rA, clockid));
                handleResult = responseMapperImpl.responseMessageClock(AppConstant.SUCCESS, response, rA, clockid);
            } else {
                logger.info(responseMapperImpl.responseMessageClock(AppConstant.ERROR, response, rA, clockid));
                handleResult = responseMapperImpl.responseMessageClock(AppConstant.ERROR, response, rA, clockid);
            }
        } else {
            if (response.contains(AppConstant.SUCCESS) || response.contains(StringUtils.capitalize(AppConstant.SUCCESS))) {
                logger.info(responseMapperImpl.responseMessageTotalCapacity(AppConstant.SUCCESS, response, rA, clockid));
                handleResult = responseMapperImpl.responseMessageTotalCapacity(AppConstant.SUCCESS, response, rA, clockid);
            } else if (response.contains(AppConstant.FAILURE) || response.contains(StringUtils.capitalize(AppConstant.FAILURE))) {
                logger.info(responseMapperImpl.responseMessageTotalCapacity(AppConstant.FAILURE, response, rA, clockid));
                handleResult = responseMapperImpl.responseMessageTotalCapacity(AppConstant.FAILURE, response, rA, clockid);
            } else {
                logger.info(responseMapperImpl.responseMessageTotalCapacity(AppConstant.ERROR, response, rA, clockid));
                handleResult = responseMapperImpl.responseMessageTotalCapacity(AppConstant.ERROR, response, rA, clockid);
            }
        }
    } else {
        ErrorResponse errorResponse = new ErrorResponse();
        ResponseStatusMsg responseStatusMsg = new ResponseStatusMsg();
        responseStatusMsg.setStatusCode(HttpStatus.NOT_FOUND.value());
        errorResponse.setClockId(clockid);
        errorResponse.setResourceId(rA.getResourceID());
        responseStatusMsg.setError("Failure in getting response from the "+url);
        errorResponse.setResponse(responseStatusMsg);
        List<ErrorResponse> errorList = new ArrayList();
        errorList.add(errorResponse);
        responseObject.setError(errorList);
        logger.info(responseObject.toString());
        handleResult = responseObject.toString();
    }
    // 用结果集合代替原future集合收集处理后的返回值
    resultList.add(handleResult);
}

三、响应和错误处理注意事项

  • 原异步场景下handle的正常返回、异常捕获逻辑可以100%复用,不需要调整判断规则
  • 原异步逻辑中为了把异常传递给handle抛出的RuntimeException可以删掉,同步场景下直接把异常赋值给error变量即可,避免打断整个循环
  • 如果业务不需要保留所有处理后的结果,也可以删掉resultList相关逻辑,保持方法无返回即可

内容的提问来源于stack exchange,提问作者Jeevan Gyawali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 23:18:02