如何让Uni.combine().all().unis()收集失败?及与Uni.join()的差异
Uni.combine与Uni.join的失败处理及差异解答
1. 能否让Uni.combine().all().unis()实现失败收集功能?
Uni.combine().all().unis()默认行为是快速失败:只要其中一个Uni调用失败,整个组合会立即终止并抛出该失败,不会等待其他Uni完成,也不会收集所有失败。如果要实现类似Uni.join().all(...).andCollectFailures()的失败收集效果,需要手动给每个Uni添加失败处理逻辑:
- 定义一个封装类,用来包装每个服务调用的成功结果或失败信息,比如:
public class ServiceResult<T> { private T result; private Throwable failure; // 构造方法、getter/setter省略 }
- 给每个Uni添加失败捕获,将失败包装成
ServiceResult实例:
Uni<ServiceResult<TypeA>> serviceAResult = serviceA.call() .map(result -> new ServiceResult<>(result, null)) .onFailure().recoverWithItem(failure -> new ServiceResult<>(null, failure)); Uni<ServiceResult<TypeB>> serviceBResult = serviceB.call() .map(result -> new ServiceResult<>(result, null)) .onFailure().recoverWithItem(failure -> new ServiceResult<>(null, failure));
- 用
Uni.combine().all().unis()组合这些处理后的Uni,最后统一检查所有结果是否存在失败:
Uni<Tuple2<ServiceResult<TypeA>, ServiceResult<TypeB>>> combined = Uni.combine().all().unis(serviceAResult, serviceBResult); combined.onItem().transform(tuple -> { ServiceResult<TypeA> aResult = tuple.getItem1(); ServiceResult<TypeB> bResult = tuple.getItem2(); List<Throwable> failures = new ArrayList<>(); if (aResult.getFailure() != null) failures.add(aResult.getFailure()); if (bResult.getFailure() != null) failures.add(bResult.getFailure()); if (!failures.isEmpty()) { throw new CompositeException(failures); } // 处理成功结果 return new CombinedResult(aResult.getResult(), bResult.getResult()); });
不过注意:你的实际需求是「只要一个服务失败就整体失败」,这种情况下Uni.combine().all().unis()的默认行为就完全符合要求——它会在第一个失败发生时立即终止并抛出异常,不需要额外处理失败收集。
2. Uni.combine().all().unis()与Uni.join(...)的核心差异
失败处理逻辑
Uni.combine().all().unis():默认快速失败,第一个失败触发后立即终止组合,不等待其他任务。要收集所有失败必须手动封装结果。Uni.join().all(...):默认同样是快速失败,但调用.andCollectFailures()后会等待所有任务完成,将所有失败打包成CompositeException返回,不会提前终止。
返回结果结构
Uni.combine().all().unis():返回结构化的元组(Tuple2/Tuple3...),能直接保留每个异构服务的结果类型,无需手动转型,适合需要明确区分不同服务结果的场景。Uni.join().all(...):返回Uni<List<Object>>(异构类型时),所有结果被统一放到列表中,需要手动转型为对应类型;如果是同构类型则返回Uni<List<T>>。
使用场景
- 优先用
Uni.combine().all().unis():当你需要异构结果的结构化返回,且希望快速失败时。 - 优先用
Uni.join().all(...).andCollectFailures():当你需要收集所有失败信息,或者对结果结构要求不高的批量任务场景。
内容的提问来源于stack exchange,提问作者Carla C
相关产品推荐
相关产品推荐

