【问题标题】:Method call after returning Mono<Void>返回 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

标签: java reactive-programming spring-webflux project-reactor


【解决方案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() 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-07
        • 1970-01-01
        • 2015-10-03
        • 1970-01-01
        • 2021-05-08
        • 1970-01-01
        • 1970-01-01
        • 2018-11-20
        相关资源
        最近更新 更多