spring-boot - 使用 Reactive webclient 递归调用 Mono 函数
问题描述
需要从 Mono 递归调用 Mono 以获得完整的 Item。我有一个 Pojo Item ,在这里我将传递根 id 并尝试从另一个服务中获取该项目。我正在使用 sprign webflux 编写我的服务。所以我使用 webclient 来调用服务并返回 Mono
另一项服务将提供项目及其直系子项。所以我的要求是当我传递 ROOT id 时,我将获得 Root 项及其直接子项,Root 将具有 LM 类型的项作为子项。
获得 Root 项目后,我需要收集所有 LM id 并再次为每个 LM id 调用 ItemService 并将它们设置回根项目。
这是我的代码。发生的事情首先是我的 RootItem 正在返回,然后获取 LM 项目的调用正在订阅。我想首先获取所有 LM 项目并将它们设置为 root 并用新的 LM 项目响应 RootItem。
String itemId,
String ItemName,
List<Item> items
ItemType itemType
}
Enum ItemType {
LM,ROOT,LEAF
}
getItem(itemId) {
// Returns Mono<Item> by calling anthoer service which gives me Item . Here I am using Reactive webclient to call other service.
}
getFullItem(itemId) {
return getItem(itemId)
.flatMap(mainItem -> {
Predicate<Item> LM_Prdicate = p -> p.getItemType().equals(LM);
// get the LM's from main item. at this point the LM items will not have child
//we need to get the LM item indvidually to get its child and set back to main item.
List<Item> LMSwihtouchild = mainItem.getItems().stream().filter(LM_Prdicate).collect(Collectors.toList());
LMSwihtouchild.forEach(lmWihtoutChild -> {
getItem(lmWihtoutChild.getId()) // here I am calling recursively to get the LM Item so that it will come with children
.flatMap(lmWithChildren -> {
mainItem.getItems().removeIf(item -> item.getId().equals(lmWihtoutChild.getId())); // removing the LM item with out child from main item
mainItem.getContentItems().add(lmWithChildren); //Adding LM item with Children
return Mono.just(mainItem);
})
.subscribe()
});
return Mono.just(mainItem); // This retruning to as response before calling and getting the LM items with children.
});
}
解决方案
您需要制作方法链。你不应该在.subscribe()
里面执行,.flatMap
因为它没有连接到你的主方法链。
我已经按照您的示例制作了伪代码。
getFullItem(itemId) {
return getItem(itemId)
.flatMap(mainItem -> {
Predicate<Item> LM_Prdicate = p -> p.getItemType().equals(LM);
List<Item> LMSwihtouchild = mainItem.getItems().stream().filter(LM_Prdicate).collect(Collectors.toList());
// make flux from List<Item>. It's connected to your method chain.
return Flux.fromIterable(LMSwihtouchild)
.flatMap(child -> getItem(child.getId())
.collectList()
.map(childList -> {
// merge result here
mainItem.getItems().removeIf(item -> item.getId().equals(lmWihtoutChild.getId()));
mainItem.getContentItems().add(lmWithChildren);
return mainItem;
}
});
});
}
推荐阅读
- c# - C# 有类似 Pascal 记录类型的东西吗?
- python-3.x - 覆盖列表(对象)
- python - 如果用户输入字符串而不是整数,我如何使代码重新运行
- java - 如何将其定向到正确的位置?
- c# - 如何以编程方式更改IP地址?
- javascript - Alexa 技能 .getResponse() 有什么作用?
- ruby - Ruby 递归索引/搜索方法(使用中间比较)返回不正确的索引值
- javascript - How to sink field value to nested JSON with lodash
- json - 如何使Vue显示来自json文件的本地路径的图像
- ibm-watson - 是否可以在 Watson 助手中获取 Slack 用户名作为实体?