4

我已经实现了一个虚拟的反应式存储库,但我正在努力使用更新方法:

@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);
        });
    });
}

这是对的吗?

4

2 回答 2

7

请参阅有关寻找合适运营商的参考指南

值得注意的是,Mono你有and, when, then(注意最后一个将flatMap在 3.1.0 中变为,而 flatmap 将变为flatMapMany

doOnNext更多的是用于日志记录或统计信息收集等辅助操作。订阅内订阅是另一种不好的形式;通常你想要flatMap或类似的。

于 2017-08-13T22:43:02.447 回答
3

这些天我玩了 Spring 5 Reactive Streams 的功能,并写下了一些示例代码(还没有通过博客或推特公开,我仍然需要在 Reactor 上进行更多练习)。

我也遇到了同样的问题,最后用 aMono.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() }
}
于 2017-08-17T08:16:52.877 回答