project-reactor - Project Reactor:实现有条件地映射输入Mono
问题描述
我正在尝试实现以下简单的命令式逻辑:
boolean saveImperative(final List list) {
final String existingList = readByNameImperative(list.getName());
if (Objects.isNull(existingList)) {
templateSaveImperative(existingList);
return true;
} else {
templateSaveImperative(existingList);
return false;
}
}
以声明方式使用 Project Reactor,这就是我能够实现的目标:
@Test
public void testDeclarative() {
final Mono<List> list = createList("foo");
final Boolean result = save(list).block();
System.out.println(result);
}
private Mono<Boolean> save(final Mono<List> listMono) {
final Mono<List> existingListMono = listMono.cache()
.flatMap(list -> readByName(list.getName()));
// if
final Mono<List> savedListMono = existingListMono
.flatMap(existingList -> templateSave(Mono.just(existingList)));
final Mono<Boolean> trueResult = savedListMono.map(x -> true);
// else
return trueResult.switchIfEmpty(templateSave(existingListMono).map(x -> false));
}
private Mono<List> templateSave(final Mono<List> listMono) {
return listMono.map(list -> {
System.out.println("templateSave has been called");
return list;
});
}
private Mono<List> readByName(final String listName) {
if (listName != "list001") {
return Mono.empty();
}
return createList(listName);
}
private Mono<List> createList(final String name) {
final List list = List.builder().name(name).build();
return Mono.just(list);
}
@Value
@Builder
private static class List {
private final String name;
}
如果我用 执行测试list001
,它将打印:
templateSave has been called
true
正如预期的那样,但如果我用 调用它foo
,那么我得到了
null
我会错过什么?我希望输出如下:
templateSave has been called
false
在这种情况下。
解决方案
final Mono<List> existingListMono = listMono.cache()
.flatMap(list -> readByName(list.getName()));
...在您的保存方法中,将获取您现有的列表并使用readByName()
.
您的readByName()
方法如下:
private Mono<List> readByName(final String listName) {
if (listName != "list001") {
return Mono.empty();
}
return createList(listName);
}
(我不相信它与这个问题有关,但不要使用 == 或 != 来比较字符串。)
由于您的listName
is foo
, not list001
,它返回一个空Mono
- 因此existingListMono
成为一个空 Mono,并且暗示也是如此savedListMono
and trueResult
。
但是,当您调用您的switchIfEmpty()
语句时,您传入templateSave(existingListMono)
- 并且由于如上所述existingListMono
是空的,因此该方法返回一个 empty 。Mono
save()
Mono
...并且当您阻塞空时,Mono
您将得到 null - 因此结果。
因此,您可能希望在方法的 return 语句中使用listMono
而不是,这将为您提供您所追求的结果:existingListMono
save()
trueResult.switchIfEmpty(templateSave(listMono).map(x -> false))
推荐阅读
- angular - 如何更改liveAnnouncer的语言
- scala - 应如何设置 Play 应用程序以一次按顺序处理请求?
- regex - 正则表达式 - 删除重复的字符串
- reactjs - 如何将参数传递给自定义事件侦听器并防止 reactjs 中的默认值?
- scala - scala 隐式宏应该返回什么来告诉编译器“忘记我的结果,继续你的搜索”
- react-native - 反应原生 Firebase AdMob 不在 iOS 上显示广告
- arduino - 有多少设备可以访问 ESP32 的异步网络服务器有限制吗
- php - CI4 您必须使用“set”方法来更新条目。已经用set了,还是报错
- amazon-web-services - 自动从私有 GitHub Enterprise 推送到 CodeCommit
- javascript - 如何使用 flexbox 设计排名?