【问题标题】:How to get User object from Mono<User> without blocking it in Java?如何从 Mono<User> 获取用户对象而不在 Java 中阻塞它?
【发布时间】:2020-12-26 07:17:16
【问题描述】:

我有一个存储库调用,它将给我 Mono 。

例如:

    private User getUserData (User user)
{
 Mono<User> monoUser=userRepository.insert(user);
  User user= monoUser.block; 
return user;
}

如何在不阻塞 spring 反应的情况下实现这一点。我不想做 monoUser.block 来获取 User 对象。

获取 userObject 后,我​​需要通过 Mapstruct 将 id 转换为 UserId。另外我想在不阻塞的情况下实现这一点,以便我将使用响应式功能。

【问题讨论】:

    标签: java spring spring-boot reactive spring-reactive


    【解决方案1】:

    您可以使用Mono 而不是调用block 来做很多不会阻止的事情。您可以做的一件事是将Consumer 附加到它,当Mono 的操作成功完成时会调用它。执行此操作的方法的签名(在Mono 上)是:

    Mono<T> doOnSuccess(Consumer<? super T> onSuccess)
    

    然后你可以继续工作,当操作完成时你的消费者会被调用。然后,该调用将启动您希望在添加用户后执行的任何操作。

    您将写入数据库的代码放入您的Consumer。如果该对象需要信息,例如要写入的数据库句柄,您可以在构造对象时将该信息传递给它,然后再将其传递给doOnSuccess 调用。 -

    【讨论】:

    • 但要插入数据库,我需要订阅或阻止。带有 doOnSuccess 的数据不会被插入到 Db 中。如何通过这种方法实现这一目标?
    • 请参阅我的答案末尾添加的段落 - 通过添加 Consumer,您正在订阅一个事件......用户已成功添加到存储库的事件。
    • 感谢您的建议。但有时这个 doOnSuccess 给了我 Null 对象。不是所有的时间。此外,如果我延迟 2 毫秒,它的工作正常。有什么建议吗?
    • 这很奇怪。我不知道那是什么。这种行为将是您的“userRepository”实现的一个功能,我显然对此一无所知。也许你需要忽略你得到的任何 Null 对象,你最终会得到你真正想要采取行动的对象。我不记得 doOnSuccess 是否应该导致您的 Consumer 只被调用一次,或者它是否可能被多次调用。我会认为是前者,但如果你得到 Null,我不知道你会怎么做。
    猜你喜欢
    • 2019-02-23
    • 1970-01-01
    • 1970-01-01
    • 2019-11-11
    • 2021-01-28
    • 2023-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多