【发布时间】:2019-10-29 11:19:23
【问题描述】:
我正在尝试通过重构一些当前阻塞的代码来学习反应式编程。很多次我遇到了从Mono-sequence 中设置一些可变数据对象的状态而不订阅它的问题。在旧代码中,对象的字段值是由一些阻塞服务计算的,我现在也在 Monos 中进行。
到目前为止,我通常(ab)使用flatMap 来获得预期的行为:
initExpensiveObject().flatMap(expObj -> initExpensiveField(expObj).map(expField -> {
expObj.setExpensiveField(expField);
return expObj;
})).subscribe(expObj -> System.out.println("expensiveField: " + expObj.getExpensiveField()));
import reactor.core.publisher.Mono;
public class Main {
/**
* Expensive, lazy object instantiation
*/
public static Mono<ExpensiveObject> initExpensiveObject() {
return Mono.fromCallable(ExpensiveObject::new);
}
/**
* Expensive, async mapping (i.e. database access, network request):
* ExpensiveObject -> int
*/
public static Mono<Integer> initExpensiveField(ExpensiveObject expObj) {
return Mono.just(1);
}
public static class ExpensiveObject {
private int expensiveField = -1;
public int getExpensiveField() {
return expensiveField;
}
public void setExpensiveField(int expensiveField) {
this.expensiveField = expensiveField;
}
}
}
虽然这个flatMap-pattern 有效,但我觉得应该有一个更具反应性的解决方案。考虑到仅Mono 中就有这么多运算符,直觉上将一个对象“映射”到同一个对象以改变其状态是错误的。但是,“副作用”运算符 (doOn*) 不允许在未订阅的情况下轻松转换另一个发布者。
如果我的问题没有简单的解决方案,我非常愿意改进设计,因为代码的设计仍然是顺序。
【问题讨论】:
标签: java reactive-programming project-reactor reactor