订阅后功能现在可以正常执行

时间:2018-08-31 17:16:31

标签: reactive-programming spring-webflux

我有一个Mono对象,已在其上预订了doOnsuccess,在此方法中,我再次将数据保存在DB(使用ReactiveCouchbaseRepository的CouchBase)中。之后,我没有得到Line1和Line2的任何日志。

但是,如果我不保存该对象,这就可以正常工作,这意味着我正在获取第2行的日志。

   Mono<User> result = context.getPayload(User.class);
     result.doOnSuccess( user -> {
      System.out.println("############I got the user"+user);
      userRepository.save(user).doOnSuccess(user2->{
                System.out.println("user saved");  // LINE 1
              }).subscribe();
      System.out.println("############"+user); // LINE2
    }).subscribe();

1 个答案:

答案 0 :(得分:0)

您的代码段违反了一些您应严格遵循的规则:

您不应在返回诸如subscribeMono之类的响应类型的方法/ lambda中调用Flux;这将使执行与主要任务脱钩,而他们俩仍将在该共享状态下运行。这通常会因某些问题试图读取同一数据流的两倍而最终出现问题。有点像您要创建两个单独的线程,尝试在同一输出流上读取。

您不应在doOnXYZ运算符中进行I / O操作。这些是“副作用”运算符,这意味着它们可用于记录增量计数器。

您应该尝试如何链接Reactor运算符以创建单个反应式管道并返回反应式类型以供最终客户端订阅。在Spring WebFlux应用程序中,HTTP客户端(通过WebFlux引擎)正在订阅。

您的代码段如下所示:

Mono<User> result = context.getPayload(User.class)
             .doOnSuccess(user -> System.out.println("############Received user "+user))
             .flatMap(user -> {return userRepository.save(user)})
             .doOnSuccess(user -> System.out.println("############ Saved "+user));
return result;