如何在弹簧反应堆中将两台出版商结合在一起

我实现了我的一个虚拟反应仓库。 我正在与更新方法斗争:

@Override public Mono<User> updateUser(int id, Mono<User> updateMono) { return //todo with getUser } @Override public Mono<User> getUser(int id) { return Mono.justOrEmpty(this.users.get(id)); } 

从一方面我有传入发布者Mono<User> updateMono ,另一方面,我有Mono.justOrEmpty(this.users.get(id))期间另一个出版商。

如何将它们结合在一起,进行更新,并只返回一个发布者?

我唯一想到的是:

 @Override public Mono<User> updateUser(int id, Mono<User> updateMono) { return getUser(id).doOnNext(user -> { updateMono.subscribe(update -> { users.put(id, new User(id, update.getName(), update.getAge())); System.out.format("Updated user with id %d to %s%n", id, update); }); }); } 

这是对的吗?

请参阅查找正确操作员的参考指南

值得注意的是,对于Mono你有, then (注意这最后一个将在3.1.0变成flatMap ,flatmap将变成flatMapMany

doOnNext更多用于记录或统计信息收集等副作用。 订阅里面的订阅是另一个不好的形式; 一般你想flatMap或类似的。

现在我已经玩了Spring 5 Reactive Streams功能,并且写下了一些示例代码 (不是通过博客或者twitter发布的,还需要在Reactor上进行更多的练习)。

我遇到了同样的问题,最后使用Mono.zip来更新MongoDB中的现有项目。

https://github.com/hantsy/spring-reactive-sample/blob/master/boot-routes/src/main/java/com/example/demo/DemoApplication.java

 public Mono<ServerResponse> update(ServerRequest req) { return Mono .zip( (data) -> { Post p = (Post) data[0]; Post p2 = (Post) data[1]; p.setTitle(p2.getTitle()); p.setContent(p2.getContent()); return p; }, this.posts.findById(req.pathVariable("id")), req.bodyToMono(Post.class) ) .cast(Post.class) .flatMap(post -> this.posts.save(post)) .flatMap(post -> ServerResponse.noContent().build()); } 

更新 :在Kotlin写的另一个工作版本。

 fun update(req: ServerRequest): Mono<ServerResponse> { return this.posts.findById(req.pathVariable("id")) .and(req.bodyToMono(Post::class.java)) .map { it.t1.copy(title = it.t2.title, content = it.t2.content) } .flatMap { this.posts.save(it) } .flatMap { noContent().build() } }