java - 顺序减少列表> 单声道, 如果有任何返回 false 则中止处理
问题描述
我有一个任务列表,这些任务是按顺序执行true
的,如果任务成功或false
失败则返回(非例外情况 - 第三种情况它遇到某种异常,这也应该中止处理,但我想将其视为不同的第三种情况)。
这些任务表示为Mono<Boolean>
实例列表。它们可能有任意数量。从这个列表中,我想产生一个Mono<Boolean>
具有以下特征的:
- 它按顺序执行每个任务。
- 如果列表中的任何任务返回
false
或遇到异常,它应该中止任何进一步任务的处理。 true
如果所有任务都成功则返回;false
如果任何任务非异常失败;如果任何任务遇到异常,它应该发出错误。
这是 3 个任务的示例列表 - 第一个成功,第二个失败 - 所以我不希望第三个运行:
Mono<Boolean> task1 = Mono.create(sink -> {
try {
System.out.println("Executing task 1...");
// Simulate some work being done
Thread.sleep(1000);
System.out.println("Finished executing task 1.");
// This task is successful, return true
sink.success(true);
} catch (InterruptedException e) {
sink.error(e);
}
});
Mono<Boolean> task2 = Mono.create(sink -> {
try {
System.out.println("Executing task 2...");
// Simulate some work being done
Thread.sleep(1000);
System.out.println("Finished executing task 2.");
// This task is NOT successful, return false
sink.success(false);
} catch (InterruptedException e) {
sink.error(e);
}
});
Mono<Boolean> task3 = Mono.create(sink -> {
try {
System.out.println("Executing task 3...");
// Simulate some work being done
Thread.sleep(1000);
System.out.println("Finished executing task 3.");
// This task is successful, return true
sink.success(true);
} catch (InterruptedException e) {
sink.error(e);
}
});
List<Mono<Boolean>> tasks = Arrays.asList(task1, task2, task3);
我的第一个想法是将Mono
s 列表转换为 a Flux
,然后使用Flux#reduce
:
Mono<Boolean> process = Flux.concat(tasks)
.reduce(true, (accum, value) -> accum && value);
process.subscribe(System.out::println);
这会正确生成false
,这表明过程中的步骤之一未成功(步骤 2)。但是,根据输出,很明显任务 3 仍在执行,这是不正确的:
Executing task 1...
Finished executing task 1.
Executing task 2...
Finished executing task 2.
Executing task 3...
Finished executing task 3.
false
如果我回到同步世界并使用Mono#block
,我可以获得所需的行为,但这感觉不是很惯用:
Mono<Boolean> process = Mono.create(sink -> {
Boolean result = true;
for (Mono<Boolean> task: tasks) {
result = task.block();
if (!result) {
break;
}
}
sink.success(result);
});
process.subscribe(System.out::println);
reduce
使用, map
,等内置运算符是否有更好的方法来做到这一点flatMap
?
解决方案
您可以takeUntil
根据给定条件使用停止处理:
Mono<Boolean> process = Flux.concat(tasks)
.takeUntil(x -> !x)
.reduce(true, (accum, value) -> accum && value);
推荐阅读
- node.js - 更改与其他文档相关的文档中的字段的方法
- c# - 无法统一引用游戏对象的 2D 数组
- html - 我是 html 的初学者,我的代码不起作用
- javascript - 兄弟组件不会在状态更改时重新渲染(使用 useEffect、useState 和 Context)
- swift - 当输入的值大于某个值时如何限制用户输入 Swift 5.1
- php - 在 MYSQL 中搜索拼写错误的单词的最佳方法
- scala - 在 scala 中使用 Spark Structured Streaming 从 kafka 流式传输到 kafka
- javascript - 将 props 传递给子组件时避免组件重新渲染
- cmd - 将所有文件从子文件夹复制到另一个同名的子文件夹 Windows 10
- r - 我应该如何在 R 中删除带有其他字符(例如:100g)的数字