我是反应式编程的新手(并且我读过很多类似的问题)。在我当前的宠物项目中,我遇到了以下问题(我为相关场景提供伪代码)。
它涉及过滤
Mono<Object>
,然后确定Mono<Void>
是否被调用。
在下面的例子中:
Mono<String>
String resource
适合我的方法。Mono<String>
平面映射到长期运行的 Mono<Void>
。它更改了一些内部系统属性,但不返回任何内容。service.loadSmth
被执行并成功完成,我想打电话给serviceContinueWork.doSmthElse()
public Mono<Void> execute(String resource) {
return Mono.just(resource) //Mono<String>
.filter(Objects::nonNull) //Mono<String>
.filter(msg -> msg.startsWith("http://")) //filtering the Mono<String>
.flatMap(msg -> service.loadSmth(msg)) //flat map to Mono<Void>
.doOnSuccess(command -> serviceContinueWork.doSmthElse()) //!!! executed always :(
.doOnError(t -> log.error("service#loadSmth error: {}", ExceptionUtils.getStackTrace(t)))
.then();
}
但是,无论字符串是否被过滤,都会调用
doOnSuccess
。据我了解,空的 Mono 被认为已成功终止。
这种情况的模式是什么? (当我们想要确定
Mono<Void>
是否被调用时 - doOnNext
和 doOnSuccess
不合适。)
据我了解,我总是可以切换到
service.loadSmth(msg)
返回 Mono<Boolean>
- 然后 doOnNext
而不是 doOnSuccess
就可以正常工作了。
但是,似乎应该有某种方法来区分这些情况,而无需更改不必要的签名。我需要知道是否已在外部调用代码中“从外部”调用了方法。 就像,我不会让“void doSmth()”方法返回布尔值,只是为了知道它是否已被调用(在通常的、非反应性/非功能性的情况下)。
将不胜感激任何建议/链接。
发布@MartinTarjányi 评论的答案。对我有用的伪代码:
public Mono<Void> execute(String resource) {
return Mono.just(resource)
.filter(Objects::nonNull)
.filter(msg -> msg.startsWith("http://"))
.flatMap(msg -> service
.loadSmth(msg)
.onSuccess((v) -> serviceContinueWork.doSmthElse()))
.doOnError(t -> log.error("service#loadSmth error: {}", ExceptionUtils.getStackTrace(t)))
.then();
}