如何实现CompletableFuture链式调用,串联依赖前序结果的异步任务
实现方案说明
你目前用thenApply的链式写法是正确可用的,完全匹配你想要的JS Promise链式调用的依赖传递逻辑:前序异步任务的返回值会作为参数传入下一个步骤,整个调用链路全程异步非阻塞,符合你的需求。
thenApply和thenCompose的区别
你疑惑的两个方法适用场景不同,和JS Promise的对应关系如下:
thenApply:对应JSthen里返回普通值的场景,入参是Function<T, U>,接收前一步的返回值,返回一个普通的结果值,会自动包装成新的CompletableFuture<U>向下传递,就是你现在用的场景。thenCompose:对应JSthen里返回新Promise的场景,入参是Function<T, CompletableFuture<U>>,接收前一步的返回值,返回一个新的异步任务CompletableFuture,会自动打平嵌套的Future结构,避免出现CompletableFuture<CompletableFuture<U>>的嵌套情况。
举个例子,如果你的后续方法本身是异步实现,返回CompletableFuture:
// 异步版本的secondfunc CompletableFuture<String> asyncSecondFunc(String secondStr) { return CompletableFuture.supplyAsync(() -> { // 原有的请求逻辑不变 return secondStr.concat("Done Post two"); }, ex); }
这时候链式调用就需要换成thenCompose:
promise.thenCompose(val -> asyncSecondFunc(val)) .thenCompose(val -> asyncThirdFunc(val)) .thenAccept(val -> System.out.println(val));
可选优化点
- 线程池用完记得关闭,你当前代码里的
ExecutorService没有关闭,会导致程序运行完不会自动退出,可以在链式调用配置完成后加ex.shutdown(),如果需要主线程等待所有异步任务执行完再退出,可以在最后调用返回的CompletableFuture对象的join()方法。 - 你当前三个请求方法的HTTP调用逻辑完全重复,可以抽成公共的HTTP请求工具方法,减少冗余代码。
内容的提问来源于stack exchange,提问作者Leandro Gamarra
相关产品推荐
相关产品推荐

