CompletableFuture使用案例

最近遇到一个前端接口需要批量请求接口,担心超时,所以使用批量异步的请求方式

//批量构造请求
for (ProductInfoParam productInfoParam : list) {

            CompletableFuture<FlashLiveInfo> tmp = CompletableFuture.supplyAsync(() -> {

                try {
                    String url = String.format(flashLiveUrl,productInfoParam.getProductCode(),productInfoParam.getMerchantCode(),"","");

                    //异步请求数据
                    String jsonStr = httpClientUtil.executeGetNoProxy(url);

                    JsonNode res = JacksonUtil.INSTANCE.getObjectMapper().readTree(jsonStr);
                    String result = res.get("result").asText();
                    //请求成功
                    if (StringUtils.equals("0", result)) {
                        JsonNode data = res.get("data");
                        
                        return JacksonUtil.INSTANCE.getObjectMapper().convertValue(data, FlashLiveInfo.class);
                    } else {
                        String msg = res.get("msg").asText();
                        String errorCode = res.get("errorCode").asText();
                        LOG.error("queryFlashLiveInfo query msg ={} ,errorCode={}", msg, errorCode);
                    }


                } catch (HttpClientException e) {
                    throw new RuntimeException("查询接口异常,e={}", e);
                } catch (IOException e) {
                    throw new RuntimeException("查询解析接口返回异常,e={}", e);
                }
                //这里要返回一个值,这里在后面采坑了
                return null;

            }, ThreadPool.getFrontExecutor()).whenComplete((result,throwable)->{

                //任务完成时执行。用list存放任务的返回值
                if (result != null && result.getRecordId()!=null) {
                    resultList.add(result);
                }
                //触发异常
                if (throwable != null) {
                    LOG.error("completableFuture1  error:{}", throwable);
                }

            });

            futureList.add(tmp);
        }
//
 try  {
            //多个任务
            CompletableFuture[] futureArray = futureList.toArray(new CompletableFuture[0]);
            //将多个任务,汇总成一个任务,总共耗时不超时10秒
            CompletableFuture.allOf(futureArray).get(10, TimeUnit.SECONDS);
        } catch (Exception e) {
            LOG.error("CompletableFuture.allOf Exception error e={}", e);

        }

futureArray数组 一定不能有null 元素,否则并不是等待10s,而是把NPE报错时已经跑完的任务直接返回了。我在生产就遇到了 ,所以建议 new CompletableFuture[0],不用担心越界,实际上会动态填充,但是如果数组过大,。后面的也会自动填写null ,还是会遇到我上面所说的问题。我当初写new CompletableFuture[20],预计是20个商品发送请求。结构有的请求报错,我就默认填写null到数组中了

  CompletableFuture[] futureArray = futureList.toArray(new CompletableFuture[0]);

你可能感兴趣的:(java)