web-dev-qa-db-fra.com

Appel de méthode après retour Mono <Void>

Je veux appeler la méthode lors du retour précédent Mono<Void>:

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

Méthode sendEmailreturns Mono<Void>.

Alors, comment appeler saveNotificationLog?

PD: Essayez de rendre ma question plus simple:

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

Comment appeler doOnNextou une méthode similaire après sendEmail return Mono<Void>?

5
kostepanych

doOnNext, et en général tous doOn* les méthodes des réacteurs sont des méthodes à effets secondaires. Vous n'êtes pas censé les appeler pour effectuer des opérations d'E/S ou des opérations de chaîne, mais plutôt enregistrer des choses et ne rien faire qui affecterait l'état de l'application.

Dans votre exemple de code, notificationLogReactiveRepository.save Retour Mono<Void>. saveNotificationLog renvoie void et ne s'abonne pas à l'éditeur renvoyé par notificationLogReactiveRepository.save. Cela signifie que la notification ne sera pas enregistrée, car rien ne se passe tant que vous n'êtes pas abonné .

Dans ce cas, il semble que vous essayez de chaîner des opérations - les opérateurs then sont juste faits pour cela. Votre code devrait ressembler à ceci:

@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());
}
6
Brian Clozel

Le Mono n'émettra pas de données, donc doOnNext ne sera pas déclenché. Vous devez utiliser le doOnSuccess à la place.

De plus, votre Mono doit être consommé. Sans le code, nous ne savons pas s'il l'est ou non.

Un exemple ici: j'ai ajouté subscribe() pour consommer le mono. Selon l'utilisation de votre Mono, vous devrez faire ou non la même chose.

Cette impression rien:

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

Cette impression "OK":

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

Essayez-le de cette façon:

Mono.empty().then()