如何顺序执行Mono列表,确保前一个执行完成后再启动下一个
问题根因
你当前的写法存在的核心问题是:提前通过stream.map调用了所有processGoal方法生成了Mono列表。如果processGoal返回的是热Mono(即方法调用时就直接启动了异步任务,而非等到订阅时才触发执行),那么所有任务在你构造完List<Mono<Result>>的时候就已经全部启动了,后续的Flux.concat只是按顺序接收这些任务的执行结果,根本无法控制任务的启动时机,自然达不到顺序执行的要求。
正确实现方案
不要提前构造所有Mono实例,改用concatMap延迟生成并订阅Mono,保证前一个Mono完全执行完成后,才会处理下一个任务:
private Mono<List<Result>> processGoals(List<Goal> goals, Data data) { return Flux.fromIterable(goals) // concatMap严格保证顺序:前一个Mono完成才会处理下一个元素,生成并订阅下一个Mono .concatMap(goal -> processGoal(goal, data)) .collectList(); }
补充说明
如果你确认processGoal返回的是标准冷Mono(只有订阅时才会触发执行),那原Flux.concat的写法按理可以实现顺序执行,出现提前执行的情况几乎都是热Mono导致的,改用上述concatMap延迟生成Mono的方案是最稳妥的通用解法。
内容的提问来源于stack exchange,提问作者Sabareesh Kkanan
相关产品推荐
相关产品推荐

