【问题标题】:void vs Mono<Void> in Spring webfluxSpring webflux 中的 void 与 Mono<Void>
【发布时间】:2021-11-09 04:14:10
【问题描述】:

我最近开始使用响应式流开发 Spring Webflux 应用程序。我有 2 个问题。

  1. voidMono&lt;Void&gt;有什么区别

  2. 我有一个类似以下的用例,我认为可以使用 voidMono&lt;Void&gt; 进行改进

     @Service
     public class ABCService {  
       public Mono<String> getGreeting(String name) {
         Mono.just(NameValidator.validate(name))
              .map(isValid -> "Hello, "+name+". Welcome!");
       }
    
     }
    
     public class NameValidator {
    
       public static boolean validate(String name) {
         if(StringUtils.isEmpty(name)) {throw new RuntimeException("Invalid name");}
         return true;
    
      }
    
     }
    

我实际上并不需要 validate() 方法具有 boolean 返回类型。它可能是void/Mono&lt;Void&gt;。我只返回true 在ABCService 中执行链接。有人可以使用voidMono&lt;Void&gt; 解释如何做同样的事情

【问题讨论】:

  • Mono.fromRunnable(() -&gt; NameValidator.validate(name)).thenReturn("Hello, "+name+". Welcome!") - 这是执行此操作的惯用方式
  • 如果我想在反应式管道中间使用验证器怎么办?像这样,Mono.just(name) .map(n -&gt; n.toUpperCase()) .map(name -&gt; { NameValidator.validate(name); return name; }) .map(name -&gt; "Hello, "+name+ ". Welcome!"); 我知道这是一个人为的例子,但我有一个类似的用例
  • 我会在 doOnNext 而不是地图中使用它。
  • 我有 2 个问题,1. doOnNext() 什么时候被调用? 2. 这取决于我放置它的位置吗?如果我将 doOnNext() 作为最后一个 method() VS 如果我在这些地图之间使用它,它的行为会有所不同吗?如果我希望在我进行验证的确切位置调用它怎么办,即在上面示例中的 2 个映射之后。
  • 运算符是按声明顺序执行的,所以它的位置很重要。

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


【解决方案1】:

如果您返回 Mono,则不能使用 map()。我的意思是你可以使用它,但是因为Mono&lt;Void&gt; 永远不会发出一个值而只会发出一个完成信号,所以你的map() 永远不会生效。您需要将其替换为 then():

@Service
public class ABCService {  
  public Mono<String> getGreeting(String name) {
      NameValidator.validate(name)
         .then(Mono.just("Hello, "+name+". Welcome!"));
  }
}

【讨论】:

  • 如果我想将验证器用于已经存在的反应链怎么办?像这样,Mono.just(name).map(n -&gt; n.toUpperCase()).map(name -&gt; { NameValidator.validate(name); return name; }).map(name -&gt; "Hello, "+name+ ". Welcome!");
  • 这也可以,但老实说,这可能要简单得多。从头到尾你并不真的需要 Mono。除非您可以利用这样做的任何优势,否则仅为了创建 Mono 而创建 Mono 没有任何目的。在你的例子中,我怀疑它是否有帮助。
  • 我是 webflux 的新手。您能否在我的评论中建议/展示执行上述示例的实际方法 (Mono.just(name).map(n -&gt; n.toUpperCase()).....) 这个示例有点做作,但我在工作中做过类似的事情,但我没有得到 name管道的底部,而是从其上方的另一个对象派生的对象。
  • 在验证之前你想对 name 做什么?仅将其转换为大写? name 是一个简单的字符串(不是字符串的单声道)吗?
  • 为简单起见,假设我只是在验证之前转换为大写。它也可能是其他东西,而不是toUpperCase() 一种不同的方法,必须确定执行。是的,name 是一个字符串。 Mono.just() 会给我们一个Mono&lt;String&gt;
猜你喜欢
  • 2021-05-08
  • 2020-10-08
  • 2021-12-17
  • 2019-09-19
  • 1970-01-01
  • 2018-11-20
  • 2020-03-08
  • 2019-03-26
  • 2018-06-05
相关资源
最近更新 更多