Java中CompletableFuture supplyAsync与handle链式调用参数传递原理及示例
CompletableFuture的参数传递与链式调用解析
一、supplyAsync如何向handle()传递参数
CompletableFuture的链式调用依赖内部回调机制,你看不到直接的参数传递代码,是因为逻辑封装在它的异步执行框架里:
supplyAsync启动异步任务后,任务执行结束(不管成功返回结果,还是抛出异常),CompletableFuture会标记自身完成状态,并保存结果或异常。- 调用
handle()时,本质是给当前CompletableFuture注册了一个回调函数(你传入的BiFunction)。 - 当
supplyAsync的任务完成时,CompletableFuture会自动触发这个回调,把**任务结果(成功时为返回值,失败时为null)和异常(失败时为抛出的Throwable,成功时为null)**作为参数传给你定义的BiFunction。
简单说就是:supplyAsync的任务跑完,CompletableFuture手里就有了s和t,随后它会调用你在handle里传的函数,把这两个值塞进去执行。
二、链式调用中函数传递的简单示例
我们可以自己实现一个极简版的"Future",模拟这种链式调用里的函数传递逻辑:
import java.util.function.BiFunction; import java.util.function.Supplier; class SimpleFuture<T> { private T result; private Throwable error; // 模拟supplyAsync:执行任务,保存结果或异常 public static <T> SimpleFuture<T> supplyAsync(Supplier<T> task) { SimpleFuture<T> future = new SimpleFuture<>(); // 这里用主线程模拟异步执行,实际场景会用线程池 try { future.result = task.get(); } catch (Throwable t) { future.error = t; } return future; } // 模拟handle:接收处理函数,传递结果和异常 public <U> SimpleFuture<U> handle(BiFunction<? super T, Throwable, ? extends U> handler) { SimpleFuture<U> newFuture = new SimpleFuture<>(); try { // 把当前的结果和异常传给handler函数 newFuture.result = handler.apply(this.result, this.error); } catch (Throwable t) { newFuture.error = t; } return newFuture; } // 获取最终结果 @SuppressWarnings("unchecked") public U get() throws Throwable { if (error != null) { throw error; } return (U) result; } } // 使用示例 public class Main { public static void main(String[] args) throws Throwable { String name = null; SimpleFuture<String> future = SimpleFuture.supplyAsync(() -> { if (name == null) { throw new RuntimeException("Computation error!"); } return "Hello, " + name; }).handle((s, t) -> s != null ? s : "Hello, Stranger!"); System.out.println(future.get()); // 输出:Hello, Stranger! } }
这个示例里:
supplyAsync执行任务后,把结果/异常存在自身对象中。- 调用
handle时,将当前对象的结果和异常传给传入的BiFunction,执行后生成新的SimpleFuture返回。 - 链式调用的核心就是:前一个方法的执行结果(包括异常),会作为后一个方法中函数的参数被传递进去。
内容的提问来源于stack exchange,提问作者Rivo
相关产品推荐
相关产品推荐

