这两个调用都是客户端http api:
Flux<SavingsViewFilter> views = savingsApi.getViewFilterSavings(viewId);
Flux<Group> groups = groupsApi.getAllGroups();并返回Flux
requestBodySpec.retrieve().bodyToFlux(returnType);我需要根据eacg view.getGroupId()中的值过滤Flux<Group>中的元素
return views.flatMap(view ->
groups
.filter(group -> Objects.equals(group.getGroupId(), view.getGroupId()))
.flatMap(group -> Flux.just(DepositAccount.builder()
.agencyName(group.getGroupName())
.settlementAccount(view.getName())
.build())));它是有效的,但问题是它正在为每个视图对象执行另一个对getAllGroups的HTTP请求。
如何避免对getAllGroups的多个请求?
发布于 2020-05-28 00:23:38
问题是,您正在为视图的每个元素订阅组。
您可以使用join来仅订阅each一次,然后逐个元素地连接。
views
//Join fluxes and create tuple for each pair
.join(groups, s-> Flux.never(),s-> Flux.never(),Tuples::of)
//Filter out any that don't have matching groupIds
.filter(t -> t.getT1().getGroupId().equals(t.getT2().getGroupId()))
//Use map, not flatMap since builder is not blocking
.map(t -> DepositAccount.builder()
.agencyName(t.getT2().getGroupName())
.settlementAccount(t.getT1().getName())
.build()
);发布于 2020-05-28 01:13:25
实际上,这不是一个正确的问题,需要仔细考虑一下。
最终结果是您尝试将views的ids与groups的ids进行匹配,并创建一个join对象。这不是Flux应用编程接口的目的。最后,看起来你试图用两个循环来完成这项任务,这是一种非常低效的方式。
如果您研究其他方法,效果会更好。
1)如果group和view都与数据库表连接,则使用SQL连接。创建高效的新终结点。
2)将一个集合放入映射中,并使用它来组合两个实体。
@AllArgsConstructor
@Getter
class View {
Integer id;
String view;
}
@AllArgsConstructor
@Getter
class Group {
Integer id;
String group;
}
@Data
@AllArgsConstructor
class Combined {
String view;
String group;
}
private void run() {
Flux<View> views = Flux.just(new View(1, "v1"), new View(2, "v2"), new View(3, "v3"));
Flux<Group> groups = Flux.just(new Group(2, "g2"), new Group(3, "g3"), new Group(4, "g4"));
views.collectMap(View::getId)
.flatMapMany(viewMap -> groups.filter(group -> viewMap.containsKey(group.getId()))
.map(group ->
new Combined(viewMap.get(group.getId()).getView(), group.getGroup()))
)
.subscribe(System.out::println);
}https://stackoverflow.com/questions/62047380
复制相似问题