我目前正在用Spring WebFlux做我的第一个反应式项目。不幸的是,我已经分配了一个任务,我似乎找不到解决方案。 我想收到一个单声道并对其执行操作,具体取决于其他单声道完成的内容。我的想法是这样的:
private Mono<ResourceModel> setResourcesIfExisting(String resourceName) {
return resourceService.findByFilter(resourceName)
.flatMap(res -> service1.findByFilter(resourceName).map(res::setResource))
.flatMap(res -> service2.findByFilter(resourceName).map(res::setResource))
.flatMap(res -> service3.findByFilter(resourceName).map(res::setResource))
;
}
资源服务将找到一个 Mono,请注意,这已经是我要返回的相同类型。但是现在,我还有其他一些服务来提供资源,并且所有这些服务中应该只有一个满足的资源单体。 从我的测试来看,如果我使用这些flatMaps之一,它总是有效的,但是一旦我连续有两个或更多个,在更高级别方法上收集的列表就会结果为空(我正在使用上述方法对Flux<String>
的每个元素)。
有人能告诉我为什么会这样吗?如上所述,我几乎不明白我在做什么,但尝试了很多,但到目前为止没有成功。
上述输出的原因就是因为这个。
- 假设您从不为空的
resourceService.findByFilter(resourceName)
获得Mono<ResourceModel>
。 - 但是在第一次
.flatmap
通过调用service1.findByFilter(resourceName)
之后,它可能会返回空。 - 返回空后,不会调用其他
flatmap
,因为不会返回任何元素,因为flatmap
被调用到每个元素。
或者,您可以使用以下内容来实现您的期望
private Mono<ResourceModel> setResourcesIfExisting(String resourceName) {
return resourceService.findByFilter(resourceName)
.flatMap(res -> service1.findByFilter(resourceName)
.switchIfEmpty(service2.findByFilter(resourceName))
.switchIfEmpty(service3.findByFilter(resourceName))
.doOnEach(stringSignal -> res.setResource(stringSignal.get()))
.thenReturn(res));
}
thenReturn
将返回ResourceModel
,即使所有服务1,2,3 返回空。