Java Spring Boot中如何链式调用多个CompletableFuture实现指定异步流程
现有代码正确性判断
你当前的代码是错误的,存在两个问题:
thenCompose方法要求传入的函数必须接收上游CompletableFuture的返回值作为入参,你写的无参lambda不符合方法签名要求,编译无法通过。- 方法名拼写错误,
postToEnpointB缺少字母d,正确拼写为postToEndpointB。
如果不需要传递f1的执行结果给f2,只需要f1执行成功后启动f2,可以调整为以下写法(根据你f2的返回类型二选一即可):
- 若
postToEndpointB返回CompletableFuture类型:
CompletableFuture<String> f2 = CompletableFuture.supplyAsync(() -> postToEndpointA(a)) // ignored参数表示忽略f1的返回结果 .thenCompose(ignored -> postToEndpointB(b));
- 若
postToEndpointB是同步方法且不需要返回值:
CompletableFuture<Void> f2 = CompletableFuture.supplyAsync(() -> postToEndpointA(a)) .thenRun(() -> postToEndpointB(b));
拼接f3的实现方案
你要求无论f1、f2执行成功还是失败都要触发f3,直接在f2后链式调用whenComplete(同步执行f3)或whenCompleteAsync(异步执行f3)即可,完整示例如下:
CompletableFuture<Void> finalTask = CompletableFuture.supplyAsync(() -> postToEndpointA(a)) .thenCompose(ignored -> postToEndpointB(b)) // 入参res是f2的成功返回值,throwable是f1/f2执行抛出的异常,不需要可以直接占位忽略 .whenComplete((res, throwable) -> { // 此处执行f3的逻辑 runF3(); });
如果需要获取f3的执行结果作为整个链式调用的返回值,可以将whenComplete替换为handle方法:
CompletableFuture<String> finalTask = CompletableFuture.supplyAsync(() -> postToEndpointA(a)) .thenCompose(ignored -> postToEndpointB(b)) .handle((res, throwable) -> { // 执行f3并返回结果 return postToEndpointC(c); });
注意事项
- 如果f1执行失败,f2的逻辑会直接跳过,异常会传递到
whenComplete/handle的throwable参数中,最终f3仍会正常执行,完全符合你的需求。 - 异步执行f3时建议指定自定义线程池,避免使用
CompletableFuture默认的公共ForkJoin池,防止业务逻辑互相影响。
内容的提问来源于stack exchange,提问作者Appden65
相关产品推荐
相关产品推荐

