Webflux中能否并行调用两服务,依首个结果决定是否等待第二个?
需求可行性分析与实现方案
这个需求完全可行,核心是要让服务A和B并行执行,而非当前代码中等待A完成后再启动B的串行逻辑。
当前代码的问题
你当前的代码里,monoB只有在flatMap的else分支中才会被订阅执行,导致当A返回"a"时,B是在A结束后才开始运行,总耗时为A的2000ms加上B的8000ms,最终约10000ms,不符合你期望的8000ms耗时要求。
修改后的实现代码
要实现A返回"A"时耗时约2000ms、返回"a"时耗时约8000ms的效果,只需让A和B同时启动执行,再根据A的结果决定是否等待B的返回:
public Mono<String> test() { Mono<String> monoA = Mono.fromCallable(() -> { try { log.info("A Started"); Thread.sleep(2000); log.info("A Ended"); return Math.random() > 0.5 ? "A" : "a"; } catch (InterruptedException e) { throw new RuntimeException(e); } }).subscribeOn(Schedulers.boundedElastic()); // 使用share()确保多个订阅共享同一个执行实例,避免重复触发B的逻辑 Mono<String> monoB = Mono.fromCallable(() -> { try { log.info("B Started"); Thread.sleep(8000); log.info("B Ended"); return "B"; } catch (InterruptedException e) { throw new RuntimeException(e); } }).subscribeOn(Schedulers.boundedElastic()).share(); long startTime = System.currentTimeMillis(); return monoA.flatMap(aResult -> { if (aResult.equals("A")) { // 直接返回A的结果,无需等待B完成 return Mono.just(aResult); } else { // 等待已并行启动的B完成,返回其结果 return monoB; } }).map(response -> { long totalTime = System.currentTimeMillis() - startTime; return "Returning '" + response + "' in: " + totalTime + " ms"; }); }
效果验证
- 当A返回"A"时,输出示例:
A Started B Started A Ended Returning 'A' in: 2035 ms
此时B会继续执行至结束,但我们无需等待,总耗时约2000ms,符合预期。
- 当A返回"a"时,输出示例:
A Started B Started A Ended B Ended Returning 'B' in: 8021 ms
A和B并行执行,A结束后只需等待B剩余的执行时间,总耗时约8000ms,完全满足需求。
内容的提问来源于stack exchange,提问作者Marcos
相关产品推荐
相关产品推荐

