java8 CompletableFuture 与 es6 Promise 对比分析

1. 时间线和借鉴关系

时间线

  • JavaScript Promise:最早出现在 2007 年(Dojo 框架),2015 年成为 ES6 标准

  • Java CompletableFuture:2014 年随 Java 8 引入

借鉴关系

  • CompletableFuture 借鉴了 Promise 的核心思想,但扩展了更多功能:

  • 两者都实现了 Future 模式

  • 都支持链式调用和组合操作

  • CompletableFuture 从 JavaScript Promise(以及 Scala、C# 等语言)中汲取了设计灵感

  • 但 CompletableFuture 提供了更丰富的 API,更像是一个"Promise on steroids"

2. 核心 API 对比

功能分类CompletableFuture (Java)Promise (ES6+)备注
创建supplyAsync(), runAsync(), completedFuture()new Promise(), Promise.resolve(), Promise.reject()
转换thenApply(), thenAccept(), thenRun()then()CompletableFuture 更细粒度
组合thenCompose(), thenCombine(), acceptEither()then() 链式调用CompletableFuture 更丰富
多任务组合allOf(), anyOf()all(), race(), allSettled(), any()ES2021 新增 any()
异常处理exceptionally(), handle(), whenComplete()catch(), finally()CompletableFuture 更灵活
完成控制complete(), completeExceptionally(), obtrudeValue()只能在 executor 中 resolve/rejectCompletableFuture 可外部完成
超时控制orTimeout(), completeOnTimeout() (Java 9+)需要自己实现或使用 Promise.raceCompletableFuture 内置支持
结果依赖thenApplyAsync(), thenComposeAsync() 等带 Async 的方法then() 自动异步CompletableFuture 可指定线程池
获取结果get(), join(), getNow()await (async/await)
取消操作cancel()无内置取消机制
延迟执行需要手动实现new Promise() 立即执行
进度报告无内置支持无内置支持都需要自己实现
  • 创建异步任务
// CompletableFuture
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "result");
CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {});

// 手动控制完成
CompletableFuture<String> future3 = new CompletableFuture<>();
future3.complete("result");
future3.completeExceptionally(new Exception());
// Promise
const promise = new Promise((resolve, reject) => {
    // 异步操作
    resolve("result");
    // 或 reject(new Error())
});
  • 转换和组合
// CompletableFuture
future.thenApply(result -> result + " transformed")
      .thenAccept(System.out::println)
      .thenRun(() -> System.out.println("Done"));

// 组合多个Future
CompletableFuture.allOf(future1, future2);
CompletableFuture.anyOf(future1, future2);
// Promise
promise.then(result => result + " transformed")
       .then(console.log)
       .then(() => console.log("Done"));

// 组合多个Promise
Promise.all([promise1, promise2]);
Promise.race([promise1, promise2]); // 类似 anyOf
Promise.allSettled([promise1, promise2]);
  • 异常处理
// CompletableFuture
future.exceptionally(ex -> "fallback")
       .handle((result, ex) -> {
           // 同时处理结果和异常
           return ex != null ? "error" : result;
       })
       .whenComplete((result, ex) -> {
           // 清理操作,类似 finally
       });
// Promise
promise.catch(error => "fallback")
       .finally(() => {
           // 清理操作
       });

// 没有直接的 handle 方法,需要自己包装

3. 特色功能对比

CompletableFuture 特有功能

// 1. 手动完成(从外部完成Future)
CompletableFuture<String> future = new CompletableFuture<>();
new Thread(() -> {
    // 某个条件达成后
    future.complete("done");
}).start();

// 2. 依赖多个Future的结果
future1.thenCombine(future2, (r1, r2) -> r1 + r2);
future1.thenAcceptBoth(future2, (r1, r2) -> System.out.println(r1 + r2));

// 3. 竞争第一个完成的(但处理所有结果)
future1.applyToEither(future2, result -> result);

// 4. 超时控制(Java 9+)
future.orTimeout(1, TimeUnit.SECONDS);
future.completeOnTimeout("default", 1, TimeUnit.SECONDS);

// 5. 指定执行线程池
future.thenApplyAsync(transformation, customExecutor);

Promise 特有功能

// 1. async/await 语法糖(ES2017+)
async function fetchData() {
    try {
        const result = await promise;
        console.log(result);
    } catch (error) {
        console.error(error);
    }
}

// 2. Promise.allSettled() (ES2020)
// 等待所有Promise完成,无论成功失败
Promise.allSettled([promise1, promise2])
    .then(results => {
        results.forEach(result => {
            if (result.status === 'fulfilled') {
                console.log('成功:', result.value);
            } else {
                console.log('失败:', result.reason);
            }
        });
    });

// 3. 微任务队列
// Promise回调在微任务队列执行,优先级高于宏任务

4. 设计哲学差异

CompletableFuture 特点:

  • 功能丰富:提供了大量的组合方法

  • 显式控制:可以手动完成、取消、指定执行器

  • 同步点:提供了 get()、join() 等阻塞方法

  • 集成并发工具:与 Java 的 Executor 框架深度集成

Promise 特点:

  • 简单一致:API 相对简单,核心是 then/catch/finally

  • 不可取消:一旦创建,无法从外部取消

  • 微任务调度:基于事件循环,回调在微任务队列执行

  • 语言级集成:与 async/await 语法深度集成

5. 使用场景建议

使用 CompletableFuture 当:

// 需要复杂组合逻辑
CompletableFuture<List<String>> result = 
    CompletableFuture.supplyAsync(() -> fetchUsers())
        .thenCompose(users -> 
            CompletableFuture.supplyAsync(() -> processUsers(users))
        )
        .exceptionally(ex -> fallbackList());

// 需要手动控制完成
CompletableFuture<Data> cacheFuture = new CompletableFuture<>();
if (cache.hasData()) {
    cacheFuture.complete(cache.getData());
} else {
    loadDataAsync().thenAccept(data -> {
        cache.setData(data);
        cacheFuture.complete(data);
    });
}

// 需要超时控制
future.orTimeout(5, TimeUnit.SECONDS)
      .exceptionally(ex -> defaultData());

使用 Promise 当:

// 简单异步流程
fetch(url)
    .then(response => response.json())
    .then(data => process(data))
    .catch(error => handleError(error))
    .finally(() => cleanup());

// 使用 async/await 简化
async function processUser(userId) {
    try {
        const user = await fetchUser(userId);
        const orders = await fetchOrders(user.id);
        return { user, orders };
    } catch (error) {
        console.error(error);
        return null;
    }
}

// 并行处理多个异步任务
const [user, products] = await Promise.all([
    fetchUser(),
    fetchProducts()
]);

6. 总结

相同点:

  • 都实现了 Future/Promise 模式

  • 都支持链式调用和组合

  • 都用于解决回调地狱问题

主要差异:

维度CompletableFuturePromise
设计理念功能全面,适合复杂业务逻辑简单一致,适合Web异步编程
完成控制可以从外部手动完成只能在executor内部完成
取消机制支持取消不支持
线程控制可以指定执行器由事件循环控制
语法集成没有特殊语法糖有 async/await 语法糖
多任务组合方法更丰富(thenCombine等)提供静态方法(all/race等)

发展趋势:

  • Promise 影响了 CompletableFuture 的设计

  • CompletableFuture 反过来又影响了后续的 JavaScript 提案(如取消机制的讨论)

  • 两者都在各自生态中持续演进,吸收对方优点

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐