如何在弹簧反应堆中将两台出版商结合在一起
我实现了我的一个虚拟反应仓库。 我正在与更新方法斗争:
@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中的现有项目。
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() } }