返回 Mono<Void> 后的方法调用

Posted

技术标签:

【中文标题】返回 Mono<Void> 后的方法调用【英文标题】:Method call after returning Mono<Void> 【发布时间】:2019-01-02 01:27:48 【问题描述】:

我想调用之前返回Mono&lt;Void&gt;时的方法:

 @Override
 public Mono<Void> sendEmail(EmailDto emailDto) 
 return mailReactiveClient.sendEmail(message ->
     createMessage(emailDto, emailDto.getBody(), message))
       .doOnNext(saveNotificationLog(emailDto)); //it's not work


  private void saveNotificationLog(EmailDto emailDto) 
    notificationLogReactiveRepository.save(NotificationLog.builder()
       ...
      .build());
  

方法sendEmail返回Mono&lt;Void&gt;

那么如何拨打saveNotificationLog

UPD:让我的问题更简单:

 @Override
 public Mono<Void> sendEmail(EmailDto emailDto) 
 return mailReactiveClient.sendEmail(message ->
     createMessage(emailDto, emailDto.getBody(), message))
       .doOnNext(System.out.print("Hello world!"); 

sendEmail返回Mono&lt;Void&gt;后如何调用doOnNext或类似方法?

【问题讨论】:

notificationLogReactiveRepository 阻塞了吗? 不,它将 NotificationLog obj 存储在 DB 中并返回 Mono 【参考方案1】:

Mono 不会发出数据,所以doOnNext 不会被触发。您应该改用doOnSuccess

另外,你的 Mono 需要被消耗掉。没有代码,我们不知道是不是。

这里有一些例子:我添加了subscribe() 来消费单声道。根据您对 Mono 的使用,您将不得不做或不做同样的事情。

这什么也没有打印出来:

Mono<String> m=Mono.just("test");
Mono<Void> v=m.then();
v.doOnNext(x->System.out.println("OK")).subscribe();

这个打印“OK”:

Mono<String> m=Mono.just("test");
Mono<Void> v=m.then();
v.doOnSuccess(x->System.out.println("OK")).subscribe();

【讨论】:

【参考方案2】:

doOnNext,通常所有doOn*反应器方法都是副作用方法。您不应该调用它们来进行 I/O 工作或链式操作,而是记录事物而不做任何会影响应用程序状态的事情。

在您的代码示例中,notificationLogReactiveRepository.save 返回Mono&lt;Void&gt;saveNotificationLog 返回void 并且不订阅notificationLogReactiveRepository.save 返回的发布者。这意味着通知不会被保存,因为nothing happens until you subscribe。

在这种情况下,您似乎正在尝试链接操作 - then 运算符就是为此而生的。您的代码应如下所示:

@Override
public Mono<Void> sendEmail(EmailDto emailDto) 
    return mailReactiveClient.sendEmail(message ->
        createMessage(emailDto, emailDto.getBody(), message))
           .then(saveNotificationLog(emailDto));


private Mono<Void> saveNotificationLog(EmailDto emailDto) 
    return notificationLogReactiveRepository.save(NotificationLog.builder()
        ...
        .build());

【讨论】:

【参考方案3】:

试试这个方法:

Mono.empty().then() 

【讨论】:

以上是关于返回 Mono<Void> 后的方法调用的主要内容,如果未能解决你的问题,请参考以下文章

反应堆映射 Mono<Boolean> 到 Mono<Void>

在 Mono<String> 中转换 Mono<Void> 添加一个值

static

Spring 5 新特性:函数式Web框架

如何合并动态 Mono 返回方法

Spring Webflux:控制器返回 Mono<ResponseEntity<MyPojo>> vs Mono<MyPojo>